| name | description |
|---|---|
mapbox-search-patterns |
Expert guidance on choosing the right Mapbox search tool and parameters for geocoding, POI search, and location discovery |
Expert guidance for AI assistants on using Mapbox search tools effectively. Covers tool selection, parameter optimization, and best practices for geocoding, POI search, and location discovery.
Best for: Specific places, addresses, brands, named locations
Use when query contains:
- Specific names: "Starbucks on 5th Avenue", "Empire State Building"
- Brand names: "McDonald's", "Whole Foods"
- Addresses: "123 Main Street, Seattle", "Times Square"
- Chain stores: "Target near me"
- Cities/places: "San Francisco", "Central Park"
Don't use for: Generic categories ("coffee shops", "museums")
Best for: Generic place types, categories, plural queries
Use when query contains:
- Generic types: "coffee shops", "restaurants", "gas stations"
- Plural forms: "museums", "hotels", "parks"
- Is-a phrases: "any coffee shop", "all restaurants", "nearby pharmacies"
- Industry terms: "electric vehicle chargers", "ATMs"
Don't use for: Specific names or brands
Best for: Converting coordinates to addresses
Use when:
- Have GPS coordinates, need human-readable address
- Need to identify what's at a specific location
- Converting user location to address
| User Query | Tool | Reasoning |
|---|---|---|
| "Find Starbucks on Main Street" | search_and_geocode_tool | Specific brand name |
| "Find coffee shops nearby" | category_search_tool | Generic category, plural |
| "What's at 37.7749, -122.4194?" | reverse_geocode_tool | Coordinates to address |
| "Empire State Building" | search_and_geocode_tool | Specific named place |
| "hotels in downtown Seattle" | category_search_tool | Generic type + location |
| "Target store locations" | search_and_geocode_tool | Brand name (even plural) |
| "any restaurant near me" | category_search_tool | Generic + "any" phrase |
| "123 Main St, Boston, MA" | search_and_geocode_tool | Specific address |
| "electric vehicle chargers" | category_search_tool | Industry category |
| "McDonald's" | search_and_geocode_tool | Brand name |
Three ways to spatially constrain search results:
What it does: Biases results toward a location, but doesn't exclude distant matches
Use when:
- User says "near me", "nearby", "close to"
- Have a reference point but want some flexibility
- Want results sorted by relevance to a point
Example:
{
"q": "pizza",
"proximity": {
"longitude": -122.4194,
"latitude": 37.7749
}
}Why this works: API returns SF pizza places first, but might include famous NYC pizzerias if highly relevant
What it does: Hard constraint - ONLY returns results within the box
Use when:
- User specifies an area: "in downtown", "within this neighborhood"
- Have a defined service area
- Need to guarantee results are within bounds
Example:
{
"q": "hotel",
"bbox": [-122.51, 37.70, -122.35, 37.83] // [minLon, minLat, maxLon, maxLat]
}Why this works: Guarantees all hotels are within SF's downtown area
What it does: Limits results to specific countries
Use when:
- User specifies country: "restaurants in France"
- Building country-specific features
- Need to respect regional boundaries
Example:
{
"q": "Paris",
"country": ["FR"] // ISO 3166 alpha-2 codes
}Why this works: Finds Paris, France (not Paris, Texas)
Can combine: proximity + country = "Near SF but only in USA"
| Scenario | Use | Why |
|---|---|---|
| "Find coffee near me" | proximity | Bias toward user location |
| "Coffee shops in downtown Seattle" | proximity + bbox | Center on downtown, limit to area |
| "Hotels in France" | country | Hard country boundary |
| "Best pizza in San Francisco" | proximity + country ["US"] | Bias to SF, limit to US |
| "Gas stations along this route" | bbox around route | Hard constraint to route corridor |
| "Restaurants within 5 miles" | proximity (then filter by distance) | Bias nearby, filter results |
category_search_tool only (1-25, default 10)
| Use Case | Limit | Reasoning |
|---|---|---|
| Quick suggestions | 5 | Fast, focused results |
| Standard list | 10 | Default, good balance |
| Comprehensive search | 25 | Maximum allowed |
| Map visualization | 25 | Show all nearby options |
| Dropdown/autocomplete | 5 | Don't overwhelm UI |
Performance tip: Lower limits = faster responses
Filter by feature type:
| Type | What It Includes | Use When |
|---|---|---|
poi |
Points of interest (businesses, landmarks) | Looking for places, not addresses |
address |
Street addresses | Need specific address |
place |
Cities, neighborhoods, regions | Looking for area/region |
street |
Street names without numbers | Need street, not specific address |
postcode |
Postal codes | Searching by ZIP/postal code |
district |
Districts, neighborhoods | Area-based search |
locality |
Cities, towns, villages | Municipality search |
country |
Country names | Country-level search |
Example combinations:
// Only POIs and addresses, no cities
{"q": "Paris", "types": ["poi", "address"]}
// Returns Paris Hotel, Paris Street, not Paris, France
// Only places (cities/regions)
{"q": "Paris", "types": ["place"]}
// Returns Paris, France; Paris, Texas; etc.Default behavior: All types included (usually what you want)
search_and_geocode_tool: Narrow generic searches
{
"q": "lunch",
"poi_category": ["restaurant", "cafe"],
"proximity": {"longitude": -122.4194, "latitude": 37.7749}
}When to use:
- Generic query that could match multiple categories
- Want to focus search within category
- User specifies type implicitly
category_search_tool: Use poi_category_exclusions instead
{
"category": "food_and_drink",
"poi_category_exclusions": ["bar", "nightclub"]
}When to use:
- Broad category but want to exclude subcategories
- "Restaurants but not fast food"
What it does: Enables partial/fuzzy matching
| Setting | Behavior | Use When |
|---|---|---|
true |
Matches partial words, typos | User typing in real-time |
false (default) |
Exact matching | Final query, not autocomplete |
Example:
// User types "starb"
{"q": "starb", "auto_complete": true}
// Returns: Starbucks, Starboard Tavern, etc.Use for:
- Search-as-you-type interfaces
- Handling typos ("mcdonalds" → McDonald's)
- Incomplete queries
Don't use for:
- Final/submitted queries (less precise)
- When you need exact matches
Request estimated time of arrival to results
Parameters:
eta_type: Set to"navigation"navigation_profile:"driving"|"walking"|"cycling"origin: Starting coordinates
Use when:
- User asks "how long to get there?"
- Sorting by travel time, not distance
- Need route time, not straight-line distance
Example:
{
"q": "grocery stores",
"proximity": {"longitude": -122.4194, "latitude": 37.7749},
"eta_type": "navigation",
"navigation_profile": "driving",
"origin": {"longitude": -122.4194, "latitude": 37.7749}
}Returns: Results with eta (travel time in seconds)
When NOT to use:
- Just need straight-line distance (use distance_tool offline after search)
- Budget-conscious (adds API cost)
Choose output format:
| Format | Returns | Use When |
|---|---|---|
formatted_text (default) |
Human-readable text | Displaying to user directly |
json_string |
GeoJSON as JSON string | Need to parse/process results |
Example:
formatted_text:
1. Blue Bottle Coffee
Address: 66 Mint St, San Francisco, CA
Coordinates: 37.7825, -122.4052
Type: poi
json_string:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4052, 37.7825]},
"properties": {"name": "Blue Bottle Coffee", ...}
}]
}Decision:
- Showing list to user →
formatted_text - Plotting on map →
json_string(parse and use coordinates) - Further processing →
json_string
ISO language codes (e.g., "en", "es", "fr", "de", "ja", "zh")
Use when:
- Building multilingual app
- User's language preference known
- Need localized names
Example:
{
"q": "東京タワー",
"language": "ja"
}
// Returns results in JapaneseDefault: English (if not specified)
Tip: Match user's locale for best experience
User: "Find coffee shops near me"
Optimal approach:
1. Get user's location (from app/browser)
2. Use category_search_tool:
- category: "cafe" or "coffee_shop"
- proximity: user's coordinates
- limit: 10
Why: Category tool for generic "coffee shops", proximity for "near me"
User: "Find all Starbucks in Seattle"
Optimal approach:
1. Use search_and_geocode_tool:
- q: "Starbucks"
- proximity: Seattle coordinates
- country: ["US"]
2. Or if need strict boundary:
- bbox: Seattle city bounds
Why: Brand name = search_and_geocode_tool; proximity biases to Seattle
User: "What are the coordinates of 1600 Pennsylvania Ave?"
Optimal approach:
Use search_and_geocode_tool:
- q: "1600 Pennsylvania Ave, Washington DC"
- types: ["address"] // Focus on addresses
- country: ["US"] // Narrow to US
Why: Specific address with country context for disambiguation
User: "Show me all hotels in downtown Portland"
Optimal approach:
1. Geocode "downtown Portland" → get center point
2. Define downtown bbox (or use 1-2 mile radius)
3. Use category_search_tool:
- category: "hotel"
- bbox: downtown bounds (or proximity + filter by distance)
- limit: 25 // Get comprehensive list
Why: Category for "hotels", bbox for "in downtown" hard boundary
User: "What's at these GPS coordinates?"
Optimal approach:
Use reverse_geocode_tool:
- longitude: -122.4194
- latitude: 37.7749
- types: ["address", "poi"] // Get both address and POI if available
Why: Coordinates → address is exactly what reverse geocoding does
User: "Find gas stations along my route"
Optimal approach:
1. Get route geometry from directions_tool
2. Create bbox around route (use bounding_box_tool)
3. Use category_search_tool:
- category: "gas_station"
- bbox: route bounding box
4. Filter results to those within X meters of route (use distance_tool)
Why: Bbox for rough filter, then distance calculation for precision
User: "Find ramen shops" (user locale: ja)
Optimal approach:
Use category_search_tool:
- category: "ramen_restaurant" (or "restaurant")
- language: "ja"
- proximity: user location
Why: Returns Japanese names/addresses for better UX
// BAD
category_search_tool({category: "starbucks"})
// "starbucks" is not a category, returns error
// GOOD
search_and_geocode_tool({q: "Starbucks"})// BAD
search_and_geocode_tool({q: "coffee shops"})
// Less precise, may return unrelated results
// GOOD
category_search_tool({category: "cafe"})// BAD - Results may be anywhere globally
category_search_tool({category: "restaurant"})
// GOOD - Biased to user location
category_search_tool({
category: "restaurant",
proximity: {longitude: -122.4194, latitude: 37.7749}
})// BAD - Hard boundary may exclude good nearby results
search_and_geocode_tool({
q: "pizza",
bbox: [-122.42, 37.77, -122.41, 37.78] // Tiny box
})
// GOOD - Bias toward point, but flexible
search_and_geocode_tool({
q: "pizza",
proximity: {longitude: -122.4194, latitude: 37.7749}
})// BAD - Costs API quota for routing calculations
search_and_geocode_tool({
q: "museums",
eta_type: "navigation",
navigation_profile: "driving"
})
// User didn't ask for travel time!
// GOOD - Only add ETA when needed
search_and_geocode_tool({q: "museums"})
// If user asks "how long to get there?", then add ETA// BAD - Overwhelming for simple dropdown
category_search_tool({
category: "restaurant",
limit: 25
})
// Returns 25 restaurants for a 5-item dropdown
// GOOD - Match UI needs
category_search_tool({
category: "restaurant",
limit: 5
})Pattern: Geocode once, reuse coordinates
// GOOD
1. User enters "Seattle"
2. Geocode "Seattle" → (lng, lat)
3. Use those coordinates for multiple category searches
4. Cache coordinates for session
// BAD
1. Geocode "Seattle" for coffee search
2. Geocode "Seattle" again for restaurant search
3. Geocode "Seattle" again for hotel search
| UI Context | Recommended Limit |
|---|---|
| Autocomplete dropdown | 5 |
| List view | 10 |
| Map view | 25 |
| Export/download | 25 (or paginate) |
After getting search results:
1. category_search_tool → Get POIs
2. distance_tool (offline) → Calculate distances
3. bearing_tool (offline) → Get directions
Why: Search once (API), then use offline tools for calculations (free, fast)
1. category_search_tool({category: "hospital", proximity: user_location})
→ Returns 10 hospitals with coordinates
2. distance_tool(user_location, each_hospital)
→ Calculate exact distances offline
3. Sort by distance
1. search_and_geocode_tool({q: "Space Needle"})
→ Get destination coordinates
2. directions_tool({from: user_location, to: space_needle_coords})
→ Get turn-by-turn directions
1. search_and_geocode_tool({q: "warehouse"})
→ Get warehouse coordinates
2. isochrone_tool({coordinates: warehouse, time: 30, profile: "driving"})
→ Get 30-minute delivery zone polygon
3. point_in_polygon_tool(customer_address, delivery_zone)
→ Check if customer is in delivery zone
1. category_search_tool({category: "restaurant", limit: 10})
→ Get restaurant coordinates
2. static_map_image_tool({
markers: restaurant_coordinates,
auto_fit: true
})
→ Create map image showing all restaurants
Possible reasons:
- Invalid category → Use
resource_reader_toolwithmapbox://categoriesto see valid categories - Too restrictive bbox → Expand area or use proximity instead
- No POIs in area → Try broader category or remove spatial filters
- Wrong country filter → Check country codes
Example recovery:
1. category_search_tool({category: "taco"}) → No results
2. Check: Is "taco" a valid category?
→ Use category_list_tool → See "mexican_restaurant" is valid
3. Retry: category_search_tool({category: "mexican_restaurant"}) → Success
Possible reasons:
- Typo in query → Retry with
auto_complete: true - Too specific → Broaden search (remove address numbers, try nearby city)
- Wrong types filter → Remove or expand types
- Not a recognized place → Check spelling, try alternative names
Get valid categories: Use resource_reader_tool or category_list_tool
resource_reader_tool({uri: "mapbox://categories"})
Returns: All valid category IDs (e.g., "restaurant", "hotel", "gas_station")
When to use:
- User enters free-text category
- Need to map user terms to Mapbox categories
- Validating category before search
Example mapping:
- User: "places to eat" → Category: "restaurant"
- User: "gas" → Category: "gas_station"
- User: "lodging" → Category: "hotel"
User query contains...
→ Specific name/brand (Starbucks, Empire State Building)
→ search_and_geocode_tool
→ Generic category/plural (coffee shops, museums, any restaurant)
→ category_search_tool
→ Coordinates → Address
→ reverse_geocode_tool
→ Address → Coordinates
→ search_and_geocode_tool with types: ["address"]
For local searches, ALWAYS set:
- ✅
proximity(or bbox if strict boundary needed)
For category searches, consider:
- ✅
limit(match UI needs) - ✅
format(json_string if plotting on map)
For disambiguation, use:
- ✅
country(when geographic context matters) - ✅
types(when feature type matters)
For travel-time ranking:
- ✅
eta_type,navigation_profile,origin(costs API quota)
- Forgetting proximity → Results are global/IP-based
- Using wrong tool → category_search for "Starbucks" (use search_and_geocode)
- Invalid category → Check category_list first
- Bbox too small → No results; use proximity instead
- Requesting ETA unnecessarily → Adds API cost
- Limit too high for UI → Overwhelming user
- Not filtering types → Get cities when you want POIs
Works with:
- mapbox-geospatial-operations: After search, use offline distance/bearing calculations
- mapbox-web-integration-patterns: Display search results on map in web app
- mapbox-token-security: Ensure search requests use properly scoped tokens