Skip to main content
Glama

compare_weather

Compare current weather conditions between two locations to analyze differences in temperature, precipitation, and forecasts.

Instructions

Compare current weather conditions between two locations.

This unique feature allows you to compare weather at two different places side-by-side.

Args:
    location1: First location (city name or "lat,lon" format, e.g., "New York" or "40.7128,-74.0060")
    location2: Second location (city name or "lat,lon" format, e.g., "Los Angeles" or "34.0522,-118.2437")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
location1Yes
location2Yes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'compare_weather' tool. It parses locations (city names or coordinates), fetches forecast data using NWS API, and returns a formatted side-by-side comparison of temperature, wind, humidity, precip chance, and short forecasts, including temperature difference insight.
    @mcp.tool()
    async def compare_weather(location1: str, location2: str) -> str:
        """Compare current weather conditions between two locations.
        
        This unique feature allows you to compare weather at two different places side-by-side.
    
        Args:
            location1: First location (city name or "lat,lon" format, e.g., "New York" or "40.7128,-74.0060")
            location2: Second location (city name or "lat,lon" format, e.g., "Los Angeles" or "34.0522,-118.2437")
        """
        def parse_location(loc: str) -> tuple[float, float] | None:
            """Parse location string to coordinates.
            
            Only parses if the string is clearly in "lat,lon" format (both parts are numeric).
            Returns None for city names (even if they contain commas like "New York, NY").
            """
            # Check if it's in "lat,lon" format
            if "," in loc:
                parts = loc.split(",")
                # Only try to parse if we have exactly 2 parts
                if len(parts) == 2:
                    try:
                        # Try to parse both parts as floats
                        lat_str = parts[0].strip()
                        lon_str = parts[1].strip()
                        lat, lon = float(lat_str), float(lon_str)
                        # Validate coordinates are in valid ranges
                        if validate_coordinates(lat, lon):
                            return (lat, lon)
                    except ValueError:
                        # If parsing fails, it's not coordinates (probably a city name with comma)
                        pass
            # Not in coordinate format, will need geocoding
            return None
    
        # Get coordinates for both locations
        # Try parsing as coordinates first (e.g., "40.7128,-74.0060")
        coords1 = parse_location(location1)
        if not coords1:
            # If not coordinates, try geocoding the city name
            coords1 = await geocode_location(location1)
            if not coords1:
                return f"Error: Could not find coordinates for '{location1}'. Please check the city name or use 'lat,lon' format (e.g., '40.7128,-74.0060')."
    
        coords2 = parse_location(location2)
        if not coords2:
            # If not coordinates, try geocoding the city name
            coords2 = await geocode_location(location2)
            if not coords2:
                return f"Error: Could not find coordinates for '{location2}'. Please check the city name or use 'lat,lon' format (e.g., '40.7128,-74.0060')."
    
        # Get forecast data for both locations
        forecast1 = await get_forecast_data(coords1[0], coords1[1])
        forecast2 = await get_forecast_data(coords2[0], coords2[1])
    
        if not forecast1:
            return f"Unable to fetch weather data for '{location1}' (coordinates: {coords1[0]}, {coords1[1]}). The location may be outside NWS coverage area (US territories only)."
        if not forecast2:
            return f"Unable to fetch weather data for '{location2}' (coordinates: {coords2[0]}, {coords2[1]}). The location may be outside NWS coverage area (US territories only)."
    
        loc1_info = forecast1.get("_location", {})
        loc2_info = forecast2.get("_location", {})
        loc1_str = f"{loc1_info.get('city', location1)}, {loc1_info.get('state', 'Unknown')}"
        loc2_str = f"{loc2_info.get('city', location2)}, {loc2_info.get('state', 'Unknown')}"
    
        # Get current period (first period) for each location
        period1 = forecast1["properties"]["periods"][0] if forecast1["properties"]["periods"] else None
        period2 = forecast2["properties"]["periods"][0] if forecast2["properties"]["periods"] else None
    
        if not period1 or not period2:
            return "Unable to get current conditions for comparison."
    
        result = f"🌤️  Weather Comparison\n"
        result += f"{'='*60}\n\n"
        result += f"{loc1_str:<30} | {loc2_str}\n"
        result += f"{'-'*60}\n"
        result += f"Temperature: {period1['temperature']}°{period1['temperatureUnit']:<25} | {period2['temperature']}°{period2['temperatureUnit']}\n"
        result += f"Wind: {period1['windSpeed']} {period1['windDirection']:<25} | {period2['windSpeed']} {period2['windDirection']}\n"
        
        if period1.get('relativeHumidity') and period2.get('relativeHumidity'):
            result += f"Humidity: {period1['relativeHumidity']['value']}%{'':<25} | {period2['relativeHumidity']['value']}%\n"
        
        if period1.get('probabilityOfPrecipitation') and period2.get('probabilityOfPrecipitation'):
            result += f"Precip Chance: {period1['probabilityOfPrecipitation']['value']}%{'':<22} | {period2['probabilityOfPrecipitation']['value']}%\n"
        
        result += f"\nForecast:\n"
        result += f"{loc1_str}: {period1['detailedForecast']}\n"
        result += f"{loc2_str}: {period2['detailedForecast']}\n"
    
        # Add temperature difference analysis
        temp_diff = period1['temperature'] - period2['temperature']
        if abs(temp_diff) > 5:
            warmer = loc1_str if temp_diff > 0 else loc2_str
            result += f"\n💡 {warmer} is {abs(temp_diff)}°{period1['temperatureUnit']} warmer!"
    
        return result
  • weather.py:293-293 (registration)
    The @mcp.tool() decorator registers the compare_weather function as an MCP tool.
    @mcp.tool()
  • Input schema defined in the function signature and docstring: two string parameters for locations, returns a string comparison.
    Args:
        location1: First location (city name or "lat,lon" format, e.g., "New York" or "40.7128,-74.0060")
        location2: Second location (city name or "lat,lon" format, e.g., "Los Angeles" or "34.0522,-118.2437")
    """
Behavior3/5

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

With no annotations provided, the description carries the full burden. It discloses the tool's behavior (comparison of current conditions) and input format, but lacks details on rate limits, error handling, or response structure. It doesn't contradict annotations, but could be more comprehensive.

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?

The description is appropriately sized and front-loaded: the first sentence states the core purpose, followed by a reinforcing statement, then parameter details. Every sentence adds value with no redundancy or waste.

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 the tool's moderate complexity (2 parameters, no annotations, but has output schema), the description is mostly complete: it covers purpose, usage, and parameters well. However, it could benefit from mentioning the output schema's existence or high-level return format for better context.

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

Parameters5/5

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

The schema description coverage is 0%, so the description fully compensates by explaining both parameters (location1 and location2) with clear semantics, examples, and format details ('city name or "lat,lon" format'). This adds significant value beyond the bare schema.

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 the specific action ('compare current weather conditions') and resource ('between two locations'), distinguishing it from siblings like get_current_conditions (single location) or get_forecast (future predictions). The phrase 'side-by-side' reinforces the comparative nature.

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 implies usage context by specifying 'current weather conditions' and 'two locations', suggesting when to use this tool (for comparison) versus siblings that handle single locations or forecasts. However, it doesn't explicitly state when not to use it or name alternatives.

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/zayedansari2/MCP_WeatherServer'

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