google_maps_search
Search Google Maps for businesses and places using Outscraper's data extraction. Retrieve detailed information including contact details, locations, and enriched data for market research and lead generation.
Instructions
Search for businesses and places on Google Maps using Outscraper
Args:
query: Search query (e.g., 'restaurants brooklyn usa', 'hotels paris france')
limit: Number of results to return (default: 20, max: 400)
language: Language code (default: 'en')
region: Country/region code (e.g., 'US', 'GB', 'DE')
drop_duplicates: Remove duplicate results (default: False)
enrichment: Additional services to run (e.g., ['domains_service', 'emails_validator_service'])
Returns:
Formatted search results with business information
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| limit | No | ||
| language | No | en | |
| region | No | ||
| drop_duplicates | No | ||
| enrichment | No |
Implementation Reference
- outscraper_mcp/server.py:228-332 (handler)Primary MCP tool handler for 'google_maps_search'. Decorated with @mcp.tool() for automatic registration. Validates parameters, calls OutscraperClient API method, handles asynchronous responses, formats results into readable markdown output.@mcp.tool() def google_maps_search(query: str, limit: int = 20, language: str = "en", region: Optional[str] = None, drop_duplicates: bool = False, enrichment: Optional[List[str]] = None) -> str: """ Search for businesses and places on Google Maps using Outscraper Args: query: Search query (e.g., 'restaurants brooklyn usa', 'hotels paris france') limit: Number of results to return (default: 20, max: 400) language: Language code (default: 'en') region: Country/region code (e.g., 'US', 'GB', 'DE') drop_duplicates: Remove duplicate results (default: False) enrichment: Additional services to run (e.g., ['domains_service', 'emails_validator_service']) Returns: Formatted search results with business information """ # Input validation if not query or not query.strip(): return "Error: Search query cannot be empty." if limit < 1 or limit > MAX_SEARCH_LIMIT: return f"Error: Limit must be between 1 and {MAX_SEARCH_LIMIT}." if language and len(language) != 2: logger.warning(f"Unusual language code: {language}. Standard codes are 2 characters (e.g., 'en', 'es').") try: logger.info(f"Searching Google Maps for: {query}") results = client.google_maps_search( query=query, limit=limit, language=language, region=region, drop_duplicates=drop_duplicates, enrichment=enrichment ) if not results: return "No results found for the given query." # Handle async response if isinstance(results, str) and "Request processing asynchronously" in results: return results # Format results for better readability formatted_results = [] if isinstance(results, list) and len(results) > 0: places = results[0] if isinstance(results[0], list) else results # Ensure places is a list if not isinstance(places, list): places = [places] for i, place in enumerate(places[:limit], 1): if isinstance(place, dict): name = place.get('name', 'Unknown') formatted_place = f"**{i}. {name}**\n" # Address address = place.get('full_address') or place.get('address', 'N/A') formatted_place += f" 📍 Address: {address}\n" # Rating and reviews rating = place.get('rating') reviews = place.get('reviews', 0) if rating: formatted_place += f" ⭐ Rating: {rating} ({reviews} reviews)\n" else: formatted_place += f" ⭐ Rating: No ratings yet\n" # Contact info phone = place.get('phone', 'N/A') formatted_place += f" 📞 Phone: {phone}\n" website = place.get('site', 'N/A') formatted_place += f" 🌐 Website: {website}\n" # Type/category place_type = place.get('type') or place.get('main_category', 'N/A') formatted_place += f" 🏷️ Type: {place_type}\n" if place.get('working_hours'): formatted_place += f" 🕒 Hours: {place.get('working_hours_old_format', 'N/A')}\n" formatted_place += f" 🆔 Place ID: {place.get('place_id', 'N/A')}\n" # Include enrichment data if available if place.get('emails'): formatted_place += f" 📧 Emails: {', '.join([email.get('value') for email in place.get('emails', [])])}\n" formatted_place += "---\n" formatted_results.append(formatted_place) return f"Found {len(places)} places for '{query}':\n\n" + "\n".join(formatted_results) else: return f"Search results for '{query}':\n\n" + str(results) except Exception as e: logger.error(f"Error in google_maps_search: {str(e)}") logger.error(f"Query: {query}, Limit: {limit}, Language: {language}") return f"Error searching Google Maps: {str(e)}"
- outscraper_mcp/server.py:133-177 (helper)Helper method in OutscraperClient class that constructs the API request to Outscraper's /maps/search-v3 endpoint, handles retries and timeouts, and processes the response using _handle_response.def google_maps_search(self, query: Union[List[str], str], limit: int = 20, language: str = 'en', region: str = None, drop_duplicates: bool = False, enrichment: List[str] = None) -> Union[List, Dict]: """Search Google Maps for places/businesses""" if isinstance(query, str): queries = [query] else: queries = query wait_async = len(queries) > 10 and limit > 1 params = { 'query': queries, 'language': language, 'organizationsPerQueryLimit': limit, 'async': wait_async, 'dropDuplicates': drop_duplicates } if region: params['region'] = region if enrichment: params['enrichment'] = enrichment try: response = self.session.get( f'{OUTSCRAPER_API_BASE}/maps/search-v3', params=params, headers=self.headers, timeout=60 if wait_async else 30 ) return self._handle_response(response, wait_async) except requests.exceptions.Timeout: logger.error(f"Request timeout during Google Maps search") raise Exception("Request timed out. Please try again with fewer queries or lower limit.") except requests.exceptions.ConnectionError: logger.error(f"Connection error during Google Maps search") raise Exception("Connection error. Please check your internet connection.") except requests.exceptions.RequestException as e: logger.error(f"Network error during Google Maps search: {e}") raise Exception(f"Network error: {str(e)}") except Exception as e: logger.error(f"Unexpected error during Google Maps search: {e}") raise
- outscraper_mcp/server.py:229-245 (schema)Type annotations and comprehensive docstring defining the input schema (parameters with types, defaults, descriptions) and output format for the google_maps_search tool.def google_maps_search(query: str, limit: int = 20, language: str = "en", region: Optional[str] = None, drop_duplicates: bool = False, enrichment: Optional[List[str]] = None) -> str: """ Search for businesses and places on Google Maps using Outscraper Args: query: Search query (e.g., 'restaurants brooklyn usa', 'hotels paris france') limit: Number of results to return (default: 20, max: 400) language: Language code (default: 'en') region: Country/region code (e.g., 'US', 'GB', 'DE') drop_duplicates: Remove duplicate results (default: False) enrichment: Additional services to run (e.g., ['domains_service', 'emails_validator_service']) Returns: Formatted search results with business information """
- outscraper_mcp/server.py:228-228 (registration)The @mcp.tool() decorator registers the google_maps_search function with the FastMCP server instance.@mcp.tool()