MCP server for Google Maps Platform: geocoding, places, traffic-aware travel times
Seven tools with complete input schemas and descriptions. Naming is clear and verb-based (geocode, reverse_geocode, place_search, etc.). Descriptions are detailed and contextual (avg ~180 chars), exceeding the 10 - 1024 char baseline. All parameters have type definitions and descriptions. However, output schemas are not formally documented, responses are returned as JSON strings without explicit field definitions. Error handling is minimal; no recovery guidance or categorization. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite all tools being read-only. Parameter constraints (e.g., mode enum for travel_time) are documented in descriptions but not enforced via JSON Schema enums.
Resolve a free-form address or place name to coordinates, a canonical formatted address, and a place_id. region is a ccTLD bias (e.g. 'au'; default from the MAPS_REGION env var) — results elsewhere still resolve, just rank lower.
Full detail for one place by place_id (from place_search or geocode): weekly opening hours, phone, website, rating, price level, editorial summary.
Find businesses/points of interest by free-text query (e.g. 'vet near Potts Point', 'best coffee Surry Hills'). Returns name, address, rating, open-now, phone, and place_id per result. latitude/longitude (+ optional radius_meters, default 5 km) bias results toward a point — or just put the suburb in the query. open_now=True filters to places currently open.
Find places around a point by TYPE ('what's near me') — the typed complement to place_search's free-text queries. latitude/longitude: center of the search circle. included_types: comma-separated place types, e.g. 'pharmacy', 'restaurant,cafe', 'ev_charging_station' (Places API type table); empty returns prominent places of any type. radius_meters: search radius (default 1500, max 50000). max_results: max places (default 5, max 20). rank_by_distance: True ranks nearest-first instead of by prominence.
Output schemas not formally documented. Tools return JSON strings without explicit field definitions, forcing LLMs to parse unstructured responses. Downstream tool chaining (e.g., using place_id from geocode in place_details) relies on implicit field names.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All seven tools are read-only and idempotent, but this is not declared in the tool definition. Agents cannot infer safety properties without explicit hints.
Parameter constraints documented in descriptions but not enforced via JSON Schema. travel_time 'mode' accepts 'drive|walk|bicycle|transit|two_wheeler' only, but schema lacks enum constraint. LLMs may hallucinate invalid values; validation happens server-side only.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | 2026-07-28+ | v2 |
Resolve coordinates to the nearest street address(es).
IANA time zone + UTC offset (incl. DST) at coordinates. timestamp (unix epoch seconds) evaluates DST at a specific moment; 0 = now.
Route duration and distance between two points — traffic-aware for driving, step-by-step for transit. THE tool for "when do I need to leave?". origin/destination: address, 'lat,lng', or 'place_id:<id>'. mode: drive (default) / walk / bicycle / transit / two_wheeler. departure_time: RFC3339 (e.g. '2026-07-05T08:30:00+10:00'), must be now-or-future; empty means now. For driving, the result includes the delay vs the no-traffic baseline. arrival_time: RFC3339 "be there by" time — transit mode only (the Routes API restriction). The transit answer lists each leg: line, stops, and clock times, so "leave by" falls straight out. include_tolls: for drive/two_wheeler, adds an estimated toll cost (requests an extra computation — off by default).
Error handling minimal. No recovery guidance, error categorization, or actionable messages. A failed geocode returns a raw error string; LLM cannot determine if it should retry, ask the user, or try a different tool.
place_search and place_search_nearby accept max_results but no pagination (offset/limit or cursor). Large result sets are capped client-side; no mechanism for agents to fetch additional results beyond the limit.