Skip to content

Conversation

@mattpodwysocki
Copy link
Contributor

Summary

Adds 8 fundamental geospatial calculation tools that work completely offline without requiring Mapbox API calls. These tools provide AI agents with essential spatial reasoning capabilities.

New Tools

All tools use Turf.js for accurate geospatial calculations:

  1. distance_tool - Calculate distance between coordinates using Haversine formula

    • Supports: kilometers, miles, meters, feet, nautical miles
  2. point_in_polygon_tool - Test if a point is inside a polygon

    • Useful for: "Is this delivery address in our service area?"
  3. bearing_tool - Calculate compass direction between coordinates

    • Returns: bearing in degrees (0-360°) plus cardinal direction (N, NE, E, etc.)
  4. midpoint_tool - Find geographic midpoint along great circle path

    • Useful for: "What's halfway between San Francisco and New York?"
  5. centroid_tool - Calculate center point of polygons/multipolygons

    • Returns: geometric center of any shape
  6. area_tool - Calculate polygon area

    • Supports: square meters, kilometers, acres, hectares, miles, feet
  7. bbox_tool - Calculate bounding box of any geometry

    • Works with: points, lines, polygons, multipolygons
    • Returns: [minLon, minLat, maxLon, maxLat]
  8. buffer_tool - Create buffer zones around geometries

    • Useful for: "Show me all locations within 5km of this point"
  9. simplify_tool - Reduce vertex count using Douglas-Peucker algorithm

    • Useful for: reducing file sizes, improving rendering performance

Implementation Details

  • All tools extend BaseTool (not MapboxApiBasedTool) for offline operation
  • Set openWorldHint: false to indicate no external API calls
  • Coordinate inputs use objects {longitude, latitude} instead of tuples to avoid JSON schema issues
  • OpenTelemetry tracing integrated for all tools
  • Proper error handling and structured output

SDK Update

Also updates @modelcontextprotocol/sdk from 1.25.1 → 1.25.2 to fix CVE. Updated patch file removes icons support (that belongs in #93) and keeps only output validation fixes.

Testing

✅ All 457 tests passing
✅ Build successful
✅ Input schema validation (no z.tuple() usage)
✅ Annotations tests updated for offline tools

Example Usage

// Calculate distance
await distance_tool.run({
  from: { longitude: -122.4194, latitude: 37.7749 }, // SF
  to: { longitude: -118.2437, latitude: 34.0522 },   // LA
  units: "miles"
});
// Returns: ~347 miles

// Check if point is in polygon
await point_in_polygon_tool.run({
  point: { longitude: -122.4, latitude: 37.8 },
  polygon: [[[/* SF Bay Area polygon */]]]
});
// Returns: { inside: true }

// Create 5km buffer zone
await buffer_tool.run({
  geometry: [-122.4194, 37.7749], // Point
  distance: 5,
  units: "kilometers"
});
// Returns: Polygon representing 5km buffer

🤖 Generated with Claude Code

mattpodwysocki and others added 6 commits January 5, 2026 22:28
Implements two new Mapbox Navigation API tools:

- Map Matching Tool (map_matching_tool): Snaps GPS traces to roads
  - Supports 2-100 coordinates with optional timestamps and radiuses
  - Returns confidence scores, matched geometry, and annotations
  - Handles driving, cycling, walking, and driving-traffic profiles

- Optimization Tool (optimization_tool): Solves vehicle routing problems
  - Supports up to 1000 coordinates
  - Simplified mode: auto-generates vehicle and services
  - Advanced mode: custom vehicles, services, shipments, time windows
  - Async polling mechanism (POST + GET)

Both tools include:
- Complete input/output schemas with Zod validation
- Comprehensive unit tests (19 tests total)
- Proper annotations (readOnlyHint, openWorldHint, etc.)

All 422 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit converts the OptimizationTool from a synchronous blocking tool
to an async task-based tool using the experimental MCP Tasks API.

**Problem:** The Optimization API v2 is long-running (up to 10 seconds with
polling), blocking the agent from doing other work while waiting for results.

**Solution:** Implemented task-based execution using MCP SDK 1.25.1's
experimental tasks API:

- **src/tools/optimization-tool/OptimizationTask.ts** (NEW): Task-based
  implementation with three handlers:
  - createTask: Submits optimization job to Mapbox API, returns immediately
    without blocking
  - getTask: Returns current task status (pending, working, completed, failed)
  - getTaskResult: Returns final optimization results when complete
  - Background polling runs asynchronously with proper error handling

- **src/index.ts**: Added task support to server
  - Created InMemoryTaskStore and InMemoryTaskMessageQueue
  - Updated server capabilities to include tasks: { requests: { tools: { call: {} } } }
  - Registered OptimizationTask instead of synchronous OptimizationTool
  - Fixed "Type instantiation is excessively deep" error in GetPromptRequestSchema
    handler with type assertions (workaround for MCP SDK 1.25.1 issue #985)

- **src/tools/BaseTool.ts**: Fixed TypeScript compilation error
  - Added type assertions to break complex type inference chains
  - Workaround for "Type instantiation is excessively deep" errors with
    MCP SDK 1.25.1 generic types

**Benefits:**
- Non-blocking execution - returns task ID immediately
- Agent can do other work while optimization runs in background
- Progress updates via task status messages
- Proper error handling and timeout management
- All existing tests pass (422 tests)
- Zero TypeScript compilation errors

**Testing:**
- Server starts successfully with task support
- All 422 existing tests pass
- Build completes without errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Upgrade @modelcontextprotocol/sdk from 1.21.1 to 1.25.1
- Remove old SDK 1.21.1 patch
- Apply SDK 1.25.1 patch with icons support and output validation fixes
- Update version to 0.8.1 to match main branch
- All 422 tests passing

This brings the task-based optimization branch up to date with the latest
SDK and includes the necessary patches for proper operation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements the first offline geospatial tool using Turf.js for calculating
great-circle distance between two geographic coordinates.

Features:
- Calculate distance between any two points on Earth
- Support for multiple units: km, miles, meters, feet, nautical miles
- Haversine formula for accurate great-circle distance
- Completely offline - no API calls required
- Fast local calculations with OpenTelemetry tracing

Technical details:
- Uses Turf.js distance function
- Follows project patterns (BaseTool, proper annotations)
- Coordinate format: { longitude, latitude } objects (not tuples)
- Read-only, idempotent, closed-world tool
- Full test coverage with 8 test cases

Dependencies added:
- @turf/turf: Comprehensive geospatial analysis library

All 433 tests passing ✅

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement fundamental geospatial calculation tools that work completely
offline without requiring Mapbox API calls:

- point_in_polygon_tool: Test if a point is inside a polygon
- bearing_tool: Calculate compass direction between coordinates
- midpoint_tool: Find geographic midpoint between two points
- centroid_tool: Calculate center point of polygons
- area_tool: Calculate polygon area in various units (meters, km, acres, etc)
- bbox_tool: Calculate bounding box of any geometry
- buffer_tool: Create buffer zones around geometries
- simplify_tool: Reduce vertex count while preserving shape

All tools:
- Extend BaseTool (not MapboxApiBasedTool) for offline operation
- Use Turf.js (@turf/turf) for geospatial calculations
- Include OpenTelemetry tracing
- Have proper annotations (openWorldHint: false)
- Use coordinate objects for inputs to avoid JSON schema issues

Updated test annotations to include all offline tools in exclusion list.
All 457 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update SDK from 1.25.1 to 1.25.2 which includes security fixes.
Update patch file to match new SDK version.

All 457 tests passing with updated SDK.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@mattpodwysocki mattpodwysocki requested a review from a team as a code owner January 7, 2026 19:43
Explicitly verify that the optimization tool sends version: 1 in the
request body to the v2 endpoint, which accepts V1 format for
backward compatibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
mattpodwysocki and others added 2 commits January 7, 2026 18:06
- Switch optimization_tool to use V1 synchronous GET API (publicly available)
- V1 supports 2-12 coordinates, simple TSP, works immediately
- Preserve V2 implementation as OptimizationV2Tool (not registered)
- V2 code ready to enable when API becomes public
- Remove task-based infrastructure from main registration
- All 456 tests passing

V1 endpoint: GET /optimized-trips/v1/{profile}/{coordinates}
V2 endpoint: POST /optimized-trips/v2 (requires beta access)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
# Conflicts:
#	package-lock.json
#	package.json
#	src/index.ts
#	src/tools/BaseTool.ts
@mattpodwysocki
Copy link
Contributor Author

Closing to recreate with offline-only tools (splitting API tools into separate PR)

@mattpodwysocki mattpodwysocki deleted the offline_tools branch January 7, 2026 23:48
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