GeoWire MCP server — place search, geocoding, directions, isochrones & area analysis over 10 map providers (no API key to start)
GeoWire MCP demonstrates solid tool design with consistent naming (verb_noun pattern), comprehensive descriptions (avg 180 chars, within 10-1024 baseline), and well-structured JSON schemas. All 10 tools have input schemas with typed parameters and descriptions. However, output schemas are not explicitly documented in the source, and error handling guidance is minimal. Tool descriptions are clear but lack dependency hints and recovery guidance. No tool annotations (readOnlyHint) despite all being read-only operations.
Analyze a commercial area / neighborhood: given a center point, radius, and business types, return how many of each exist nearby, their density (per km²), rating landscape, and top places. Use this for market/competition questions — 'how saturated is coffee here', 'is this a good spot for a bakery', 'what's the dining scene within 1km'. Example: {"center": {"latitude": 37.4979, "longitude": 127.0276}, "radiusMeters": 1000, "categories": ["cafe", "restaurant", "convenience store"]}. Works with any configured providers; richer with Google/Foursquare (ratings). Not demographic data — it's a place-density/competition view built from live search.
Compute a matrix of travel distances and times from each origin to each destination (N origins × M destinations) in one call. No API key needed. Use this to rank/compare many candidates by drive time — e.g. 'which of these 5 stores is closest to the customer' or delivery/logistics assignment. Example: {"origins": [{"latitude": 37.57, "longitude": 126.98}], "destinations": [{"latitude": 37.49, "longitude": 127.02}, {"latitude": 37.51, "longitude": 127.05}]}. rows[i][j] is origins[i] → destinations[j]. Public OSRM supports driving only.
Convert a street address or place name into geographic coordinates and a normalized address. Use this when you have an address string and need latitude/longitude. Example: {"address": "1600 Amphitheatre Parkway, Mountain View, CA"}. To search for businesses by name/category, use search_places.
Get demographics (population, median age, median household income, households) for the area containing a coordinate. Use this for market context — 'who lives around here', income/age of an area. Requires a demographics provider: US Census (free key, US only). Returns null outside coverage. Example: {"location": {"latitude": 37.7749, "longitude": -122.4194}}. For a full commercial picture combine with analyze_area, which folds this in automatically.
Output schemas not documented. Tool descriptions state what is returned (e.g., 'places ranked by relevance/distance, each with location, address, contact, opening hours') but formal output schema definitions are absent from source. LLMs cannot plan downstream tool calls or extract specific fields without documented return types.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All 10 tools are read-only operations, but this is not declared via MCP tool annotations. Agents cannot infer safety/idempotency without explicit hints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2025-06-18+ | v2 |
Get a route (driving directions) between two or more waypoints, with total distance, travel time, and per-leg breakdown. Works with no API key (OpenStreetMap routing via OSRM). Use this for 'how do I get from A to B', 'how far by car', or 'how long to drive' questions. Waypoints are {latitude, longitude} in order (start, [via...], end). Example: {"waypoints": [{"latitude": 37.5665, "longitude": 126.9780}, {"latitude": 37.4979, "longitude": 127.0276}]}. Set geometry:true to also get the route polyline. Note: the public OSRM server supports driving only.
Compute a travel-time reachability area (isochrone): from an origin, the region reachable within N minutes of driving/walking/cycling, as a GeoJSON polygon + area in km². No API key (OpenStreetMap routing). Use for site selection / catchment questions — 'what's within a 15-minute drive', 'how big is this store's 10-min catchment'. Example: {"origin": {"latitude": 37.7749, "longitude": -122.4194}, "minutes": 15, "mode": "driving"}. It's an approximation (sampled bearings scored by a distance matrix), not a routing-engine isochrone.
Fetch full details for a single place by its provider reference id, in the form 'provider:providerPlaceId' (e.g. 'google:ChIJN1t_tDeuEmsRUsoyG83frY4'), as found in a place's `sources`. Only providers that support getPlace can resolve a reference — currently Google (needs an API key). OpenStreetMap/Nominatim does not, so a 'nominatim:...' reference returns nothing; use search_places or geocode_address for OSM instead. Internal 'gwp_' ids cannot be resolved directly. Example: {"id": "google:ChIJN1t_tDeuEmsRUsoyG83frY4"}.
List the geo data providers currently configured, with their capabilities, enabled state, priority, and required attribution. Use this to understand which data sources are available (e.g. whether Google is configured) before choosing a strategy or explaining coverage. Takes no arguments.
Convert geographic coordinates into the nearest address / place. Example: {"location": {"latitude": 37.5665, "longitude": 126.9780}}.
Search for places (businesses, points of interest, landmarks) by a natural-language query, optionally biased to a coordinate (`near`) and/or restricted to a country. Returns places ranked by relevance/distance, each with location, address, contact, opening hours, and its data source(s). Use this for 'find X near Y' requests. Example: {"query": "24-hour pharmacy", "near": {"latitude": 10.7769, "longitude": 106.7009}, "radiusMeters": 2000}. To turn an address into coordinates use geocode_address instead; to look up one known place use get_place.
Error handling lacks recovery guidance. Descriptions mention limitations (e.g., 'Nominatim does not support getPlace') but do not guide LLMs on what to do when a call fails. No error classification (retryable vs user-fixable vs fatal) or actionable error messages documented.
Missing dependency hints in descriptions. Tools like get_place reference 'sources' field from search_places, but descriptions do not explicitly state 'Call search_places first to obtain a provider reference id.' This forces agents to infer multi-step workflows.
Numeric parameter constraints incomplete. Tools like get_isochrone accept 'minutes' and get_directions accepts 'radiusMeters' without documented min/max bounds. Unbounded numbers risk invalid API calls (e.g., 999999 minutes, negative radius).