mapbox-search-patterns

Expert guidance on choosing the right Mapbox search tool and parameters for geocoding, POI search, and location discovery

Best for: Engineers integrating location or search features who want to avoid a week of trial-and-error with Mapbox docs.

Engineering / planning-thinkingatomicfor-engineersno-setupfrom-text

Source

Creator's repository · mapbox/mapbox-agent-skills

View on GitHub

License: MIT

Skill file

Preview skill file
---
name: mapbox-search-patterns
description: Expert guidance on choosing the right Mapbox search tool and parameters for geocoding, POI search, and location discovery
---

# Mapbox Search Patterns Skill

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.

## Available Search Tools

### 1. search_and_geocode_tool

**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", "1 Times Square"
- Chain stores: "Target"
- Cities/places: "San Francisco", "Portland"

**Don't use for:** Generic categories ("coffee shops", "museums")

### 2. category_search_tool

**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

### 3. reverse_geocode_tool

**Best for:** Converting coordinates to addresses, cities, towns, postcodes

**Use when:**

- Have GPS coordinates, need human-readable address
- Need to identify what's at a specific location
- Converting user location to address

## Tool Selection Decision Matrix

| 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 POI       |
| "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               |

## Parameter Guidance

### Proximity vs Bbox vs Country

**Three ways to spatially constrain search results:**

#### 1. proximity (STRONGLY RECOMMENDED)

**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:**

```json
{
  "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

**Critical:** Always set proximity when you have a reference location! Without it, results are IP-based or global.

#### 2. bbox (Bounding Box)

**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:**

```json
{
  "q": "hotel",
  "bbox": [-122.51, 37.7, -122.35, 37.83] // [minLon, minLat, maxLon, maxLat]
}
```

**Why this works:** Guarantees all hotels are within SF's downtown area

**Watch out:** Too small = no results; too large = irrelevant results

#### 3. country

**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
- Or it is otherwise clear they want results within a specific country

**Example:**

```json
{
  "q": "Paris",
  "country": ["FR"] // ISO 3166 alpha-2 codes
}
```

**Why this works:** Finds Paris, France (not Paris, Texas)

**Can combine:** `proximity` + `country` + `bbox` or any combination of the three

### Decision Matrix: Spatial Filters

| 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       |

### Setting limit Parameter

**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

### types Parameter (search_and_geocode_tool)

**Filter by feature type:**

| Type       | What It Includes                           | Use When                          |
| ---------- | ------------------------------------------ | --------------------------------- |
| `poi`      | Points of interest (businesses, landmarks) | Looking for POIs, 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` | Towns, villages                            | Municipality search               |
| `country`  | Country names                              | Country-level search              |

**Example combinations:**

```json
// Only POIs and addresses, no cities
{"q": "Paris", "types": ["poi", "address"]}
// Returns Paris Hotel, Paris Street, not Paris, France

// Only places (cities)
{"q": "Paris", "types": ["place"]}
// Returns Paris, France; Paris, Texas; etc.
```

**Default behavior:** All types included (usually what you want)

### auto_complete Parameter (search_and_geocode_tool)

**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:**

<!-- cspell:disable -->

```json
// 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)
<!-- cspell:enable -->
- Incomplete queries

**Don't use for:**

- Final/submitted queries (less precise)
- When you need exact matches

## Anti-Patterns to Avoid

### Don't: Use category_search for brands

```javascript
// BAD
category_search_tool({ category: 'starbucks' });
// "starbucks" is not a category, returns error

// GOOD
search_and_geocode_tool({ q: 'Starbucks' });
```

### Don't: Use search_and_geocode for generic categories

```javascript
// BAD
search_and_geocode_tool({ q: 'coffee shops' });
// Less precise, may return unrelated results

// GOOD
category_search_tool({ category: 'coffee_shop' });
```

### Don't: Forget proximity for local searches

```javascript
// 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 }
});
```

### Don't: Use bbox when you mean proximity

```javascript
// 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 }
});
```

### Don't: Request ETA unnecessarily

```javascript
// 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
```

### Don't: Set limit too high for UI display

```javascript
// 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
});
```

## Quick Reference

### Tool Selection Flowchart

```
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"]
```

### Essential Parameters Checklist

**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)

## Common Mistakes

1. **Forgetting proximity** -> Results are global/IP-based
2. **Using wrong tool** -> category_search for "Starbucks" (use search_and_geocode)
3. **Invalid category** -> Check category_list first
4. **Bbox too small** -> No results; use proximity instead
5. **Requesting ETA unnecessarily** -> Adds API cost
6. **Limit too high for UI** -> Overwhelming user
7. **Not filtering types** -> Get cities when you want POIs

## Reference Files

Load these for deeper guidance on specific topics:

- **`references/advanced-params.md`** — poi_category, ETA, format, and language parameters
- **`references/workflows.md`** — Common patterns: Near Me, Branded, Geocoding, Category+Area, Reverse, Route-Based, Multilingual
- **`references/optimization-combining.md`** — Performance optimization, combining tools, handling no results, category list resource