Skip to main content
Glama

find_nearby_stations

Locate nearby weather stations within a specified radius from a given geographic coordinate using latitude, longitude, and distance in kilometers.

Instructions

Find weather stations within a given radius (in km) from a given geographic coordinate.

Args: lat: Latitude in decimal degrees (e.g., 43.36) lon: Longitude in decimal degrees (e.g., -8.41) radio_km: Search radius in kilometers

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes
radio_kmNo

Implementation Reference

  • The primary handler function decorated with @mcp.tool(), implementing the logic to find nearby weather stations using haversine distance calculation.
    @mcp.tool()
    async def find_nearby_stations(lat: float, lon: float, radio_km: float = 25):
        """
        Find weather stations within a given radius (in km) from a given geographic coordinate.
    
        Args:
            lat: Latitude in decimal degrees (e.g., 43.36)
            lon: Longitude in decimal degrees (e.g., -8.41)
            radio_km: Search radius in kilometers
        """
    
        url = f"{AEMET_API_BASE}/valores/climatologicos/inventarioestaciones/todasestaciones"
        estaciones = await make_aemet_request(url)
        if not estaciones:
            return {"error": "Could not retrieve station list."}
    
        resultado = []
        for est in estaciones:
            try:
                est_dict: dict = est  # type: ignore
                est_lat = sexagesimal_to_decimal(est_dict["latitud"])
                est_lon = sexagesimal_to_decimal(est_dict["longitud"])
                dist = haversine(lat, lon, est_lat, est_lon)
                if dist <= radio_km:
                    est_dict["distancia_km"] = round(dist, 2)
                    resultado.append(est_dict)
            except Exception:
                continue
    
        return resultado
        #return sorted(resultado, key=lambda x: x["distancia_km"])
  • Supporting utility function to calculate the great-circle distance (haversine formula) between two latitude/longitude coordinates in kilometers. Used in find_nearby_stations.
    def haversine(lat1, lon1, lat2, lon2):
        # Distancia entre dos coordenadas en km
        R = 6371.0  # radio de la Tierra en km
        dlat = radians(lat2 - lat1)
        dlon = radians(lon2 - lon1)
        a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
        c = 2 * asin(sqrt(a))
        return R * c
  • Supporting utility function to parse AEMET's sexagesimal coordinate format (e.g., degrees minutes seconds with N/S/E/W) into decimal degrees. Used to process station coordinates.
    def sexagesimal_to_decimal(coord: str) -> float:
        """
        Convert AEMET-style sexagesimal string to decimal degrees.
        Examples:
            '424607N' -> 42.768611
            '070103W' -> -7.0175
        """
    
        direction = coord[-1]
        coord = coord[:-1]
    
        degrees = int(coord[:2])
        minutes = int(coord[2:4])
        seconds = int(coord[4:])
    
        decimal = degrees + minutes / 60 + seconds / 3600
        if direction in 'SW':
            decimal = -decimal
    
        return decimal
  • General helper function to make authenticated asynchronous requests to the AEMET OpenData API, handling the two-step response process.
    async def make_aemet_request(url: str) -> dict[str, Any] | list[Any] | None:
        logger.info(f"make_aemet_request")
        headers = {
            "api_key": API_KEY,
            "Accept": "application/json"
        }
        async with httpx.AsyncClient() as client:
            try:
                response = await client.get(url, headers=headers, timeout=30.0)
                response.raise_for_status()
                data_info = response.json()
                if data_info.get("estado") == 200:
                    data_url = data_info.get("datos")
                    if data_url:
                        data_response = await client.get(data_url, timeout=30.0)
                        data_response.raise_for_status()
                        content = data_response.content.decode('latin1')
                        return json.loads(content)
                return None
            except Exception as e:
                logger.error(f"Error connecting to AEMET: {str(e)}")
                return None
Install Server

Other Tools

Related 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/AnCode666/aemet-mcp'

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