Skip to main content
Glama

find_nearby_places

Search for points of interest, amenities, and establishments near a specific geographic location. Results are categorized and include details like names, coordinates, and tags, aiding in location-based decisions, recommendations, and analysis.

Instructions

Discover points of interest and amenities near a specific location.

This tool performs a comprehensive search around a geographic point to identify nearby establishments, amenities, and points of interest. Results are organized by category and subcategory, making it easy to find specific types of places. Essential for location-based recommendations, neighborhood analysis, and proximity-based decision making.

Args: latitude: Center point latitude (decimal degrees) longitude: Center point longitude (decimal degrees) radius: Search radius in meters (defaults to 1000m/1km) categories: List of OSM categories to search for (e.g., ["amenity", "shop", "tourism"]). If omitted, searches common categories. limit: Maximum number of total results to return

Returns: Structured dictionary containing: - Original query parameters - Total count of places found - Results grouped by category and subcategory - Each place includes name, coordinates, and associated tags

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoriesNo
latitudeYes
limitNo
longitudeYes
radiusNo

Implementation Reference

  • The primary handler function for the 'find_nearby_places' tool, decorated with @mcp.tool(). It fetches nearby POIs using OSMClient, groups them by category/subcategory, and returns structured results. Includes input schema in args and detailed docstring.
    @mcp.tool() async def find_nearby_places( latitude: float, longitude: float, ctx: Context, radius: float = 1000, # meters categories: List[str] = None, limit: int = 20 ) -> Dict[str, Any]: """ Discover points of interest and amenities near a specific location. This tool performs a comprehensive search around a geographic point to identify nearby establishments, amenities, and points of interest. Results are organized by category and subcategory, making it easy to find specific types of places. Essential for location-based recommendations, neighborhood analysis, and proximity-based decision making. Args: latitude: Center point latitude (decimal degrees) longitude: Center point longitude (decimal degrees) radius: Search radius in meters (defaults to 1000m/1km) categories: List of OSM categories to search for (e.g., ["amenity", "shop", "tourism"]). If omitted, searches common categories. limit: Maximum number of total results to return Returns: Structured dictionary containing: - Original query parameters - Total count of places found - Results grouped by category and subcategory - Each place includes name, coordinates, and associated tags """ osm_client = ctx.request_context.lifespan_context.osm_client # Set default categories if not provided if not categories: categories = ["amenity", "shop", "tourism", "leisure"] ctx.info(f"Searching for places within {radius}m of ({latitude}, {longitude})") places = await osm_client.get_nearby_pois(latitude, longitude, radius, categories) # Group results by category results_by_category = {} for place in places[:limit]: tags = place.get("tags", {}) # Find the matching category for category in categories: if category in tags: subcategory = tags[category] if category not in results_by_category: results_by_category[category] = {} if subcategory not in results_by_category[category]: results_by_category[category][subcategory] = [] # Add place to appropriate category and subcategory place_info = { "id": place.get("id"), "name": tags.get("name", "Unnamed"), "latitude": place.get("lat"), "longitude": place.get("lon"), "tags": tags } results_by_category[category][subcategory].append(place_info) # Calculate total count total_count = sum( len(places) for category_data in results_by_category.values() for places in category_data.values() ) return { "query": { "latitude": latitude, "longitude": longitude, "radius": radius }, "categories": results_by_category, "total_count": total_count }
  • Supporting helper method in OSMClient class that queries the Overpass API for nearby points of interest within a bounding box derived from lat/lon/radius and specified categories.
    async def get_nearby_pois(self, lat: float, lon: float, radius: float = 1000, categories: List[str] = None) -> List[Dict]: """Get points of interest near a location""" if not self.session: raise RuntimeError("OSM client not connected") # Convert radius to bounding box (approximate) # 1 degree latitude ~= 111km # 1 degree longitude ~= 111km * cos(latitude) lat_delta = radius / 111000 lon_delta = radius / (111000 * math.cos(math.radians(lat))) bbox = ( lon - lon_delta, lat - lat_delta, lon + lon_delta, lat + lat_delta ) # Build Overpass query overpass_url = "https://overpass-api.de/api/interpreter" # Default to common POI types if none specified if not categories: categories = ["amenity", "shop", "tourism", "leisure"] # Build tag filters tag_filters = [] for category in categories: tag_filters.append(f'node["{category}"]({{bbox}});') query = f""" [out:json]; ( {" ".join(tag_filters)} ); out body; """ query = query.replace("{bbox}", f"{bbox[1]},{bbox[0]},{bbox[3]},{bbox[2]}") async with self.session.post(overpass_url, data={"data": query}) as response: if response.status == 200: data = await response.json() return data.get("elements", []) else: raise Exception(f"Failed to get nearby POIs: {response.status}")

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/jagan-shanmugam/open-streetmap-mcp'

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