search_locations_by_name
Find locations by name to retrieve detailed information for selection and further use.
Instructions
Search for locations containing a specific name and allow selection to get details
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| search_term | Yes | Term to search for in location names | |
| access_token | No | Access token for Obenan API. Optional if OBENAN_LOGIN_ACCESS_TOKEN environment variable is set. |
Implementation Reference
- src/obenan_mcp_server/server.py:292-426 (handler)Implementation of the search_locations_by_name tool handler which fetches locations from the Obenan API and filters them by a search term, optionally displaying details if only one result is found.
async def handle_search_locations_by_name( arguments: dict[str, Any] | None ) -> list[types.TextContent]: # Get search term from arguments search_term = arguments.get("search_term") if not search_term: return [types.TextContent( type="text", text="β Error: Search term is required to search for locations" )] # Get token from environment variable or from arguments access_token = os.environ.get("OBENAN_LOGIN_ACCESS_TOKEN") if not access_token: return [types.TextContent( type="text", text="β Error: Access token is required. Either provide it as an argument or set the OBENAN_LOGIN_ACCESS_TOKEN environment variable." )] try: # First fetch all locations url = "https://stagingapi.obenan.com/api/v1/location/search?isLocationPage=false&isListingPage=true" headers = {"Authorization": f"Bearer {access_token}"} response = requests.get(url, headers=headers) if response.status_code == 200: data = response.json() # Format the response for better readability formatted_response = f"π Searching for locations containing: '{search_term}'\n\n" # Extract and filter locations matching_locations = [] if data and isinstance(data, dict) and "data" in data: if isinstance(data["data"], dict) and "results" in data["data"]: locations = data["data"]["results"] if locations and isinstance(locations, list): # Filter locations by search term for loc in locations: name = loc.get("name", "") if search_term.lower() in name.lower(): matching_locations.append(loc) # Display matching locations if matching_locations: formatted_response += f"Found {len(matching_locations)} matching location(s):\n\n" for i, loc in enumerate(matching_locations): name = loc.get("name", "Unknown") location_id = loc.get("id", "Unknown") formatted_response += f"{i+1}. {name} (ID: {location_id})\n" # Add instructions for getting details formatted_response += "\nπ To get details for a specific location, use the get_location_details tool with the location ID.\n" formatted_response += "Example: get_location_details({\"location_id\": \"[ID_FROM_ABOVE]\"})" # If there's only one result, automatically show details if len(matching_locations) == 1: location_id = matching_locations[0].get("id") formatted_response += f"\n\nAutomatically fetching details for the only match: {matching_locations[0].get('name')}\n" formatted_response += "==============================================\n\n" # Get location details detail_url = f"https://stagingapi.obenan.com/api/v1/location/{location_id}" detail_headers = { "Authorization": f"Bearer {access_token}", "Origin": "https://stagingapp.obenan.com" } detail_response = requests.get(detail_url, headers=detail_headers) if detail_response.status_code == 200: detail_data = detail_response.json() # Format the details if detail_data and isinstance(detail_data, dict) and "data" in detail_data: # Check if data.data is a dict with location fields or if it has a nested 'result' field location_data = detail_data["data"] # If location_data has a 'result' field, use that instead if isinstance(location_data, dict) and "result" in location_data: location_data = location_data["result"] # Basic information name = location_data.get("name", "Unknown") formatted_response += f"Name: {name}\n" internal_name = location_data.get("internalName", "Unknown") formatted_response += f"Internal Name: {internal_name}\n" # Address information address_line1 = location_data.get("addressLine1", "") address_line2 = location_data.get("addressLine2", "") city = location_data.get("city", "") postal_code = location_data.get("postalCode", "") country_code = location_data.get("countryCode", "") address_parts = [] if address_line1: address_parts.append(address_line1) if address_line2 and address_line2 != "null": address_parts.append(address_line2) if city: address_parts.append(city) if postal_code: address_parts.append(postal_code) if country_code: address_parts.append(country_code) address_str = ", ".join(filter(None, address_parts)) formatted_response += f"Address: {address_str}\n" # Contact information formatted_response += f"Phone: {location_data.get('telephone', 'N/A')}\n" formatted_response += f"Email: {location_data.get('businessEmail', 'N/A')}\n" formatted_response += f"Website: {location_data.get('website', 'N/A')}\n\n" else: formatted_response += f"\nCould not fetch details automatically: HTTP {detail_response.status_code}\n" else: formatted_response += f"No locations found matching '{search_term}'.\n" return [types.TextContent(type="text", text=formatted_response)] else: error_msg = f"β Failed to search locations: HTTP {response.status_code}\n{response.text[:500]}" return [types.TextContent(type="text", text=error_msg)] except Exception as e: error_trace = traceback.format_exc() return [types.TextContent( type="text", text=f"π¨ Error searching locations: {str(e)}\n\n{error_trace[:500]}" )]