Skip to main content
Glama
isdaniel

Weather MCP Server

get_current_weather

Retrieve current weather conditions for any city, providing temperature and weather description without requiring an API key.

Instructions

Get current weather information for a specified city. It extracts the current hour's temperature and weather code, maps the weather code to a human-readable description, and returns a formatted summary.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cityYesThe name of the city to fetch weather information for, PLEASE NOTE English name only, if the parameter city isn't English please translate to English before invoking this function.

Implementation Reference

  • The run_tool method of GetCurrentWeatherToolHandler that implements the core logic of the get_current_weather tool: validates input, fetches data from WeatherService, formats response, and returns MCP TextContent.
    async def run_tool(self, args: dict) -> Sequence[TextContent | ImageContent | EmbeddedResource]: """ Execute the current weather tool. """ try: self.validate_required_args(args, ["city"]) city = args["city"] logger.info(f"Getting current weather for: {city}") # Get weather data from service weather_data = await self.weather_service.get_current_weather(city) # Format the response formatted_response = self.weather_service.format_current_weather_response(weather_data) return [ TextContent( type="text", text=formatted_response ) ] except ValueError as e: logger.error(f"Weather service error: {str(e)}") return [ TextContent( type="text", text=f"Error: {str(e)}" ) ] except Exception as e: logger.exception(f"Unexpected error in get_current_weather: {str(e)}") return [ TextContent( type="text", text=f"Unexpected error occurred: {str(e)}" ) ]
  • The get_tool_description method defining the Tool metadata including inputSchema for 'city' parameter.
    def get_tool_description(self) -> Tool: """ Return the tool description for current weather lookup. """ return Tool( name=self.name, description="""Get current weather information for a specified city. It extracts the current hour's temperature and weather code, maps the weather code to a human-readable description, and returns a formatted summary.""", inputSchema={ "type": "object", "properties": { "city": { "type": "string", "description": "The name of the city to fetch weather information for, PLEASE NOTE English name only, if the parameter city isn't English please translate to English before invoking this function." } }, "required": ["city"] } )
  • Registers the GetCurrentWeatherToolHandler instance with the server's tool_handlers registry.
    add_tool_handler(GetCurrentWeatherToolHandler())
  • The get_current_weather method in WeatherService that performs geocoding via get_coordinates, API call to Open-Meteo for hourly forecast, finds current UTC hour, and extracts comprehensive weather variables into a structured dictionary.
    async def get_current_weather(self, city: str) -> Dict[str, Any]: """ Get current weather information for a specified city. Args: city: The name of the city Returns: Dictionary containing current weather data Raises: ValueError: If weather data cannot be retrieved """ try: latitude, longitude = await self.get_coordinates(city) # Build the weather API URL for current conditions with enhanced variables url = ( f"{self.BASE_WEATHER_URL}" f"?latitude={latitude}&longitude={longitude}" f"&hourly=temperature_2m,relative_humidity_2m,dew_point_2m,weather_code," f"wind_speed_10m,wind_direction_10m,wind_gusts_10m," f"precipitation,rain,snowfall,precipitation_probability," f"pressure_msl,cloud_cover,uv_index,apparent_temperature,visibility" f"&timezone=GMT&forecast_days=1" ) logger.info(f"Fetching current weather from: {url}") async with httpx.AsyncClient() as client: weather_response = await client.get(url) if weather_response.status_code != 200: raise ValueError(f"Weather API returned status {weather_response.status_code}") weather_data = weather_response.json() # Find the current hour index current_index = utils.get_closest_utc_index(weather_data["hourly"]["time"]) # Extract current weather data with all enhanced variables current_weather = { "city": city, "latitude": latitude, "longitude": longitude, "time": weather_data["hourly"]["time"][current_index], "temperature_c": weather_data["hourly"]["temperature_2m"][current_index], "relative_humidity_percent": weather_data["hourly"]["relative_humidity_2m"][current_index], "dew_point_c": weather_data["hourly"]["dew_point_2m"][current_index], "weather_code": weather_data["hourly"]["weather_code"][current_index], "weather_description": utils.weather_descriptions.get( weather_data["hourly"]["weather_code"][current_index], "Unknown weather condition" ), # Wind data "wind_speed_kmh": weather_data["hourly"]["wind_speed_10m"][current_index], "wind_direction_degrees": weather_data["hourly"]["wind_direction_10m"][current_index], "wind_gusts_kmh": weather_data["hourly"]["wind_gusts_10m"][current_index], # Precipitation data "precipitation_mm": weather_data["hourly"]["precipitation"][current_index], "rain_mm": weather_data["hourly"]["rain"][current_index], "snowfall_cm": weather_data["hourly"]["snowfall"][current_index], "precipitation_probability_percent": weather_data["hourly"]["precipitation_probability"][current_index], # Atmospheric data "pressure_hpa": weather_data["hourly"]["pressure_msl"][current_index], "cloud_cover_percent": weather_data["hourly"]["cloud_cover"][current_index], # Comfort & safety "uv_index": weather_data["hourly"]["uv_index"][current_index], "apparent_temperature_c": weather_data["hourly"]["apparent_temperature"][current_index], "visibility_m": weather_data["hourly"]["visibility"][current_index], } return current_weather except httpx.RequestError as e: raise ValueError(f"Network error while fetching weather for {city}: {str(e)}") except (KeyError, IndexError) as e: raise ValueError(f"Invalid response format from weather API: {str(e)}")
  • The format_current_weather_response method that transforms the structured weather data into a detailed human-readable text summary, including temperature, feels-like, wind, precipitation, pressure, UV, and visibility.
    def format_current_weather_response(self, weather_data: Dict[str, Any]) -> str: """ Format current weather data into a human-readable string with enhanced variables. Args: weather_data: Weather data dictionary from get_current_weather Returns: Formatted weather description string """ temp = weather_data['temperature_c'] feels_like = weather_data.get('apparent_temperature_c', temp) # Temperature text with "feels like" if significantly different temp_text = f"temperature of {temp}°C" if abs(feels_like - temp) > 2: temp_text += f" (feels like {feels_like}°C)" # Get wind direction as compass direction wind_dir = self._degrees_to_compass(weather_data.get('wind_direction_degrees', 0)) # Build the base weather description base_text = ( f"The weather in {weather_data['city']} is {weather_data['weather_description']} " f"with a {temp_text}, " f"relative humidity at {weather_data['relative_humidity_percent']}%, " f"and dew point at {weather_data['dew_point_c']}°C. " f"Wind is blowing from the {wind_dir} at {weather_data['wind_speed_kmh']} km/h " f"with gusts up to {weather_data['wind_gusts_kmh']} km/h." ) # Add precipitation info if present precip_mm = weather_data.get('precipitation_mm', 0) rain_mm = weather_data.get('rain_mm', 0) snow_cm = weather_data.get('snowfall_cm', 0) precip_prob = weather_data.get('precipitation_probability_percent', 0) if precip_mm > 0 or precip_prob > 20: if snow_cm > 0: base_text += f" Snowfall of {snow_cm} cm is occurring." elif rain_mm > 0: base_text += f" Rainfall of {rain_mm} mm is occurring." if precip_prob > 0: base_text += f" Precipitation probability is {precip_prob}%." # Add atmospheric data pressure = weather_data.get('pressure_hpa', 0) clouds = weather_data.get('cloud_cover_percent', 0) base_text += f" Atmospheric pressure is {pressure} hPa with {clouds}% cloud cover." # Add UV index warning if significant uv = weather_data.get('uv_index', 0) if uv > 3: uv_warning = self._get_uv_warning(uv) base_text += f" UV index is {uv:.1f} ({uv_warning})." # Add visibility visibility = weather_data.get('visibility_m', 0) if visibility > 0: visibility_km = visibility / 1000 base_text += f" Visibility is {visibility_km:.1f} km." return base_text

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/isdaniel/mcp_weather_server'

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