⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

@mattpodwysocki
Copy link
Contributor

@mattpodwysocki mattpodwysocki commented Jan 14, 2026

Summary

Implements a two-stage elicitation flow for DirectionsTool to provide better route selection UX:

Stage 1 (Routing Preferences): Ask users about their routing preferences before calling the API

  • Fastest route (tolls OK)
  • Avoid tolls (may be slower)
  • Avoid highways/motorways (driving only)
  • Avoid ferries

Stage 2 (Route Selection): Present actual routes for user selection after API call

  • Show duration (e.g., "4h 48min")
  • Show distance (e.g., "366.8km (227.9mi)")
  • Show major roads (e.g., "via I-84 East, I-90 East")
  • Show traffic levels: ✅ Light, 🟡 Moderate, ⚠️ Heavy
  • Show incident counts (e.g., "2 incident(s)")

Implementation Details

  • Helper methods: formatDuration() and formatDistance() for readable output
  • Graceful fallback: Both stages catch errors and continue without blocking
  • Works without elicitation: Returns all routes when elicitation is unavailable
  • Smart triggering: Only elicits for simple A-to-B routes (2 coordinates), not multi-waypoint
  • Forces alternatives: Stage 1 sets alternatives=true to get multiple routes for Stage 2

Test Scenarios

These scenarios demonstrate the two-stage elicitation flow. Screenshots to be added below.

Scenario 1: Full two-stage flow (NYC to Boston)

Input:

{
  "coordinates": [
    {"longitude": -74.006, "latitude": 40.7128},
    {"longitude": -71.0589, "latitude": 42.3601}
  ],
  "routing_profile": "mapbox/driving-traffic"
}

Expected behavior:

  1. Stage 1 elicitation appears asking for routing preferences
  2. User selects "Avoid tolls (may be slower)"
  3. API called with exclude=toll,cash_only_tolls
  4. Stage 2 elicitation shows 2+ routes with formatted details
  5. User selects preferred route
  6. Tool returns only the selected route

Screenshot placeholders:

  • Stage 1: Routing preferences dialog
Screenshot 2026-01-15 at 15 37 28
  • Stage 2: Route selection dialog with traffic and incident info
Screenshot 2026-01-15 at 15 37 36
  • Final result: Selected single route returned
Screenshot 2026-01-15 at 15 37 49

Scenario 2: User declines Stage 1 preferences

Input:

{
  "coordinates": [
    {"longitude": -118.24, "latitude": 34.05},
    {"longitude": -122.42, "latitude": 37.78}
  ],
  "routing_profile": "mapbox/driving"
}

Expected behavior:

  1. Stage 1 elicitation appears
  2. User declines/cancels
  3. API called without exclude parameter
  4. Stage 2 may still trigger if multiple routes returned
  5. All routes returned if Stage 2 declined or not triggered

Screenshot placeholders:

  • User declining Stage 1 dialog
Screenshot 2026-01-15 at 16 20 21
  • Result showing all routes
Screenshot 2026-01-15 at 16 20 32

Scenario 3: Walking profile (no highway option)

Input:

{
  "coordinates": [
    {"longitude": -74.006, "latitude": 40.7128},
    {"longitude": -73.99, "latitude": 40.73}
  ],
  "routing_profile": "mapbox/walking"
}

Expected behavior:

  1. Stage 1 shows only: Fastest, Avoid tolls, Avoid ferries (no "Avoid highways")
  2. User selects preference
  3. Continues with normal flow

Screenshot placeholders:

  • Stage 1 for walking profile (3 options, no highways)
Screenshot 2026-01-15 at 16 43 21

Scenario 4: Multi-waypoint route (no elicitation)

Input:

{
  "coordinates": [
    {"longitude": -74.006, "latitude": 40.7128},
    {"longitude": -73.9, "latitude": 41.0},
    {"longitude": -71.0589, "latitude": 42.3601}
  ]
}

Expected behavior:

  1. No Stage 1 elicitation (only for 2-coordinate routes)
  2. No Stage 2 elicitation
  3. Returns standard response
Screenshot 2026-01-15 at 16 43 42

Scenario 5: Exclude parameter already provided (no Stage 1)

Input:

{
  "coordinates": [
    {"longitude": -74.006, "latitude": 40.7128},
    {"longitude": -71.0589, "latitude": 42.3601}
  ],
  "exclude": "motorway"
}

Expected behavior:

  1. No Stage 1 elicitation (exclude already set)
  2. Stage 2 may still trigger if multiple routes returned
  3. Uses provided exclude parameter
Screenshot 2026-01-15 at 16 46 50

Testing

  • ✅ All existing DirectionsTool tests pass (37 tests)
  • ✅ Added 4 new tests for elicitation behavior:
    • Does not elicit when exclude already provided
    • Does not elicit for multi-waypoint routes
    • Returns multiple routes when no elicitation
    • Returns single route when only one available

Notes

  • Elicitations are draft MCP spec feature
  • Supported in VS Code and Cursor MCP clients
  • Not yet supported in Claude Desktop
  • Tool works without elicitation support (graceful fallback)

mattpodwysocki and others added 4 commits January 12, 2026 16:18
Implements MCP server icons at the correct architectural level (server
initialization) instead of at the tool level. Adds both light and dark
theme variants of the Mapbox logo using base64-encoded SVG data URIs.

- Add mapbox-logo-black.svg for light theme backgrounds
- Add mapbox-logo-white.svg for dark theme backgrounds
- Update server initialization to include icons array with theme property
- Use 800x180 SVG logos embedded as base64 data URIs

This replaces the previous incorrect approach of adding icons to
individual tools, which was not aligned with the MCP specification.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Updates the MCP SDK from 1.25.1 to 1.25.2 and recreates the output
validation patch for the new version. The patch continues to convert
strict output schema validation errors to warnings, allowing tools
to gracefully handle schema mismatches.

Changes:
- Update @modelcontextprotocol/sdk from ^1.25.1 to ^1.25.2
- Recreate SDK patch for version 1.25.2
- Remove obsolete 1.25.1 patch file
- All 397 tests pass with new SDK version

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Implements a two-stage elicitation flow for better route selection:

Stage 1 (Routing Preferences):
- Elicits user preferences before API call (tolls, highways, ferries)
- Maps preferences to exclude parameter
- Only triggers for simple A-to-B routes (2 coordinates)
- Forces alternatives=true to get multiple routes for Stage 2

Stage 2 (Route Selection):
- Presents actual routes with formatted details after API call
- Shows duration, distance, traffic levels (✅🟡⚠️), and incident counts
- User selects preferred route from 2+ alternatives
- Returns only the selected route

Helper methods:
- formatDuration: Convert seconds to "4h 48min"
- formatDistance: Convert meters to "366.8km (227.9mi)"

Graceful fallback:
- Both stages catch errors and continue
- Works without elicitation support (returns all routes)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@mattpodwysocki mattpodwysocki requested a review from a team as a code owner January 14, 2026 21:19
Same fix as PR #100 - allows duration_typical and weight_typical to be null.
This fixes the validation error when declining elicitations and getting
routes with null duration_typical values from the API.
mattpodwysocki added a commit that referenced this pull request Jan 15, 2026
…servers

Technical deep-dive comparing Mapbox MCP Server against competitors:

Key Findings:
- Mapbox: 24 tools (most comprehensive)
- TomTom: 11 tools
- Google Grounding Lite: 3 tools
- Google Community: 7 tools

Mapbox Unique Strengths:
- 9 offline geospatial tools (only server with offline capabilities)
- Most sophisticated routing (multi-waypoint, exclusions, constraints)
- Only server with map matching for GPS trace cleanup
- Only server with travel time matrices
- Production-ready monitoring (OpenTelemetry)
- MCP protocol leadership (Resources, MCP-UI, Elicitations in progress)

Competitor Strengths:
- TomTom: Real-time traffic incidents (unique)
- Google Grounding: Weather data (unique)
- Google Community: Reviews/ratings, elevation data

Document includes:
- Complete tool inventory for all servers
- Feature comparison matrices
- Use case fit analysis
- Deployment options
- Pricing comparison
- Roadmap (mentions elicitations in progress - PRs #98, #99)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant