MCP server for optimal route planning using Google Maps APIs and OR-Tools constraint solver
The Route Planner server defines 2 tools with reasonable naming and comprehensive descriptions. Tool names (get_distance_matrix, plan_optimal_route) follow verb_noun convention and are clear. Both tools have detailed descriptions (200+ characters) explaining their purpose, parameters, and return values. Input schemas are present with types and descriptions for all parameters. However, there are significant gaps: (1) output schemas are described in prose but not formally documented as structured JSON Schema; (2) no error handling guidance is provided, tools will fail on invalid geocoding or API errors without actionable recovery steps; (3) no input validation enums for the 'mode' parameter, despite listing valid values in the description; (4) missing parameter constraints (e.g., bounds on alpha/beta weights); (5) the server lacks tool annotations (readOnlyHint, idempotentHint) despite both tools being read-only queries. Description quality is strong and LLM-friendly, but execution safety and error recovery are weak.
Calculate distance and duration matrices between all pairs of points of interest. For accurate results, provide specific place names including city, region, and/or country where applicable. For example: - "Stratford, Ontario, Canada" instead of just "Stratford" - "Stratford, London, UK" instead of just "Stratford" - "Pisa, Tuscany, Italy" instead of just "Pisa" :param points_of_interest: A list of specific place names to calculate distances between. :param mode: Travel mode (DRIVE, WALK, BICYCLE, TRANSIT), defaults to "DRIVE" :returns: A dictionary containing: - **durations**: Matrix of travel times in minutes between places. - **distances**: Matrix of travel distances in kilometers between places. - **points_of_interest**: List of points of interest in the same order as matrices.
Plan an optimal route visiting all specified points of interest. Optimizes for a weighted combination of travel time and distance. Specify weights to prioritize either shorter travel time (higher alpha) or shorter distance (higher beta). For accurate results, provide specific place names including city, region, and/or country where applicable. For example: - "Stratford, Ontario, Canada" instead of just "Stratford" - "Stratford, London, UK" instead of just "Stratford" - "Pisa, Tuscany, Italy" instead of just "Pisa" :param points_of_interest: A list of specific place names to visit in optimal order. :param mode: Travel mode (DRIVE, WALK, BICYCLE, TRANSIT), defaults to "DRIVE" :param round_trip: If true, route returns to the starting point. If false, route ends at the last destination. :param time_weight: Weight for travel time in optimization (alpha), defaults to 1.0 :param distance_weight: Weight for travel distance in optimization (beta), defaults to 1.0 :returns: A dictionary containing: - **waypoints**: Ordered list of places as they should be visited. - **total_distance_km**: Total distance to travel in kilometers. - **total_duration_minutes**: Total travel time in minutes. - **mode**: The travel mode used. - **route_type**: "round_trip" if returning to start, "open_path" if ending at last destination. - **maps_url**: URL to view the route in Google Maps.
No formal output schema documentation. Tool descriptions mention return fields in prose (e.g., 'waypoints', 'total_distance_km', 'total_duration_minutes') but these are not registered as structured JSON Schema. LLMs cannot reliably extract or plan downstream tool calls without formal schema.
Missing enum constraint for 'mode' parameter. The description lists valid values (DRIVE, WALK, BICYCLE, TRANSIT), but the schema declares type 'string' with no enum. LLMs may hallucinate invalid modes; the server will error without guidance. Should be: {"type": "string", "enum": ["DRIVE", "WALK", "BICYCLE", "TRANSIT"]}.
No error handling guidance. Geocoding can fail (ambiguous place names, API errors, invalid coordinates), and the Distance Matrix API can timeout or return partial data. The source code raises ValueError on ambiguity and API failures, but the tool definitions do not document recovery actions (e.g., 'If geocoding fails, ask the user to be more specific with city/region/country').
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 78 | 2026-07-28+ | v2 |
Missing numeric constraints on weights. The 'time_weight' and 'distance_weight' parameters (plan_optimal_route) accept any number but lack bounds. Should specify: minimum 0.0 (or 0.1), maximum 100 (or 1000), and step/precision. Unbounded numeric inputs risk absurd values or numerical instability.
No tool annotations. Both tools are read-only queries (GET semantics, no side effects). Should declare readOnlyHint: true in tool metadata to signal to agents that these are safe for repetition. FastMCP may not yet expose this annotation API, but the definition should account for it.
Parameter descriptions include example place names ('Stratford, Ontario, Canada') which LLMs may reuse literally in production calls. Should replace examples with formal constraints (e.g., 'Include city, region, and/or country for disambiguation') or move examples to separate guidance.