Skip to main content
Glama
gitPratikSingh

Weather MCP Server

search_locations

Find location names by entering a search query to identify places for weather data retrieval.

Instructions

Search for location names matching a query string

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query for location name

Implementation Reference

  • Core implementation of the search_locations tool: searches OpenWeatherMap geo API for locations matching the query, with caching and mock fallback.
    async def search_locations(self, query: str) -> List[Dict]:
        """
        Search for locations matching the query.
        
        Args:
            query: Search query string
            
        Returns:
            List of matching locations
        """
        query = query.strip()
        
        # If no API key, return mock locations
        if not self.api_key:
            return self._get_mock_locations(query)
        
        try:
            async with httpx.AsyncClient() as client:
                url = "https://api.openweathermap.org/geo/1.0/direct"
                params = {
                    "q": query,
                    "limit": 5,
                    "appid": self.api_key
                }
                response = await client.get(url, params=params, timeout=10.0)
                response.raise_for_status()
                data = response.json()
                
                locations = []
                for item in data:
                    locations.append({
                        "name": item.get("name", ""),
                        "country": item.get("country", ""),
                        "state": item.get("state", ""),
                        "lat": item.get("lat", 0),
                        "lon": item.get("lon", 0),
                    })
                
                return locations
                
        except httpx.HTTPError:
            # Fallback to mock locations on API error
            return self._get_mock_locations(query)
  • main.py:65-78 (registration)
    Tool registration in list_tools(): defines name, description, and input schema for search_locations.
    Tool(
        name="search_locations",
        description="Search for location names matching a query string",
        inputSchema={
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Search query for location name"
                }
            },
            "required": ["query"]
        }
    ),
  • main.py:115-127 (handler)
    Dispatch handler in call_tool(): extracts query argument, validates, calls weather_api.search_locations, and returns JSON response.
    elif name == "search_locations":
        query = arguments.get("query", "")
        if not query:
            return [TextContent(
                type="text",
                text="Error: query parameter is required"
            )]
        
        locations = await weather_api.search_locations(query)
        return [TextContent(
            type="text",
            text=json.dumps(locations, indent=2)
        )]
  • Helper function providing mock location data when API key is missing or on API error.
    def _get_mock_locations(self, query: str) -> List[Dict]:
        """Return mock location search results for demo purposes."""
        # Common cities that might match
        common_cities = [
            {"name": "New York", "country": "US", "state": "New York", "lat": 40.7128, "lon": -74.0060},
            {"name": "London", "country": "GB", "state": "", "lat": 51.5074, "lon": -0.1278},
            {"name": "Paris", "country": "FR", "state": "", "lat": 48.8566, "lon": 2.3522},
            {"name": "Tokyo", "country": "JP", "state": "", "lat": 35.6762, "lon": 139.6503},
            {"name": "San Francisco", "country": "US", "state": "California", "lat": 37.7749, "lon": -122.4194},
        ]
        
        # Filter by query (case-insensitive)
        query_lower = query.lower()
        matches = [city for city in common_cities if query_lower in city["name"].lower()]
        
        # If no matches, return all cities
        return matches if matches else common_cities[:3]
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 of behavioral disclosure. It only states the basic action without details like search scope (e.g., global vs. local), result format, pagination, rate limits, or error handling. For a search tool with zero annotation coverage, this is insufficient.

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 a single, efficient sentence with zero waste. It's front-loaded and appropriately sized for a simple search tool, making it easy for an agent to parse quickly.

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

Completeness2/5

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

Given the lack of annotations and output schema, the description is incomplete. It doesn't explain what the tool returns (e.g., list of locations, IDs, coordinates) or behavioral aspects like search behavior. For a tool with no structured data beyond the input schema, more context is needed.

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

Parameters3/5

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

The input schema has 100% description coverage, with the 'query' parameter fully documented. The description adds no additional meaning beyond the schema, such as query syntax examples or matching criteria. Baseline 3 is appropriate when the schema does the heavy lifting.

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

Purpose4/5

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

The description clearly states the tool's purpose as 'Search for location names matching a query string,' which includes a specific verb ('Search') and resource ('location names'). However, it doesn't differentiate from sibling tools like get_current_weather or get_weather_forecast, which are weather-related rather than location search tools, so it doesn't need sibling differentiation here.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention any context, prerequisites, or exclusions, such as whether it's for autocomplete, exact matches, or how it relates to weather tools. This leaves the agent without usage direction.

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/gitPratikSingh/weather_mcp_server'

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