bbox-mcp-server
bbox-mcp-server is a free geospatial MCP server for AI agents that supports OpenStreetMap search, coordinate/bounds conversion, H3 grids, routing, elevation, spatial calculations, and shareable map links.
Convert, buffer, project, and format bounding boxes across WKT, GeoJSON, raw coordinates, tiles, and ogrinfo extents, with 3,900+ EPSG projections.
Search or count OpenStreetMap features via Overpass within an area or radius, and discover correct OSM tags by category.
Generate H3 cell indices for bounding boxes/polygons and aggregate OSM results into H3 hexagons for density analysis.
Create shareable URLs to inspect bounding boxes on an interactive map.
Reverse geocode coordinates to addresses and OpenStreetMap details.
Calculate driving, walking, and cycling routes with distance, duration, and geometry.
Get point elevations or sample terrain grids using 90m Copernicus DEM data.
Perform offline spatial calculations such as geometry relations, containment, distance/bearing, and grid subdivisions.
Enables natural language location lookup via Mapbox's geocoding API, allowing users to specify areas by name (e.g., 'Seattle') without needing explicit coordinates.
Provides tools for querying OpenStreetMap data through the Overpass API, enabling searches for points of interest, roads, and other mapped features within a specified area, as well as H3-based spatial aggregation.
🌍 bbox-mcp-server
FREE Geospatial tools for AI agents, with results you can inspect on a map.
Search OpenStreetMap, convert coordinates, generate H3 grids, calculate routes, and sample terrain elevation. 10 MCP tools, no API keys required to get started. Spatial results include shareable links to the interactive map.
Try asking
“Find cafes near Times Square.”
“Find me pizza near the Colosseum?”
“Eiffel Tower to the Louvre: walk or bike? Compare the routes.”
“Where are Manhattan’s coffee hotspots?”
“EV road trip: find chargers within 5km of Monterey.”
“How high up is Denver, really?”
Related MCP server: Mapbox MCP Server
Quick start
Requires Node.js 18+. Add this to your MCP client configuration:
{
"mcpServers": {
"bbox": {
"command": "npx",
"args": ["-y", "bbox-mcp-server"]
}
}
}Client | Configuration file |
Claude Desktop |
|
Cursor |
|
Windsurf |
|
VS Code (GitHub Copilot) |
|
Tools
Tool | What it does |
| Find, buffer, convert, and project bounding boxes across formats and coordinate systems. |
| Generate H3 cells for a bounding box or exact polygon boundary, including holes. |
| Create a shareable map link for a bounding box. |
| Resolve coordinates to an address and OpenStreetMap details. |
| Find or count OSM features within an area, bounding box, or radius. |
| Find OSM tags by category using curated suggestions and Taginfo fallback. |
| Group OSM query results into H3 hexagons for density analysis. |
| Get driving, walking, or cycling distance, duration, and route geometry. |
| Get elevation for points or sample a terrain grid using the 90m Copernicus DEM. |
| Calculate geometry relations, point containment, distance/bearing, and grid subdivisions offline. |
Your MCP client discovers each tool's full parameter and output schemas automatically. H3 tools use resolution (0–15).
Inputs and outputs
Tools with a location parameter accept place names. Tools with a bbox parameter auto-detect raw coordinates, single points, z/x/y tiles, WKT, GeoJSON, GeoJSON bboxes, and ogrinfo extents.
Coordinate order: raw bboxes default to lat1,lng1,lat2,lng2; points use lat,lng. Use GeoJSON or WKT to avoid ambiguity, for example {"bbox":[-74.006,40.712,-73.985,40.758]} in west/south/east/north order. coord_order on get_bounds controls formatted output only.
get_bounds supports 3,900+ bundled projections via epsg and nine output formats: csv, wkt, geojson-bbox, geojson-polygon, leaflet, overpass, ogc-bbox, kml, and stac-bbox.
For Overpass searches, supply a selector such as nwr["amenity"="cafe"]; the server adds spatial filters. Set radius_meters for an explicit distance or omit it to search the area. Use list_osm_tags to find selectors by category.
Configuration
Place search uses Nominatim with Photon fallback; a Mapbox token is optional. Defaults work without configuration.
Add an env object alongside command and args in your server configuration.
Variable | Purpose / default |
| Identify your application and contact; defaults to the server name, version, and repository URL. |
| Optional contact email for Nominatim requests. |
| Geocoder endpoint; defaults to |
| Fallback geocoder; defaults to |
| Optional additional geocoding fallback. |
| Custom Overpass endpoint(s); defaults rotate across public instances. |
| Preferred routing endpoint; defaults use public OSRM services. |
| Elevation endpoint; defaults to |
| H3 generation cap; defaults to |
For developers
Successful calls return readable content and structuredContent matching the tool's output schema, including provenance, complete, and warnings. Spatial tools also return share_url. Errors use isError: true; structured logs go to stderr, keeping stdout reserved for MCP.
To run from source:
npm install
npm test
npm startnpm test builds the server and runs the test suite.
Data and service use
Data © OpenStreetMap contributors. Public services have usage limits: avoid bulk scraping and frequent polling, and configure your own endpoints for shared or heavy workloads.
Nominatim and FOSSGIS routing limit requests to 1 per second. Nominatim also requires application identification, caching, and attribution. The server's per-process queue does not cover traffic across multiple instances.
Photon's public endpoint is a demo service without availability guarantees.
Open-Meteo's free API is for non-commercial use. Elevation grids return sample statistics, not guaranteed terrain-wide extrema or slopes.
Available Tools
10 toolsaggregate_overpass_h3ARead-onlyIdempotent
Executes an Overpass query and bins the results into H3 hexagons at a specified resolution to analyze spatial density. Plots the top density hotspots on the shareable verification map.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | The bounding box geometry to parse. | |
| query | Yes | The Overpass QL core query (e.g. `nwr["amenity"="cafe"]`). | |
| location | No | A text location to search for (e.g. 'Seattle'). | |
| resolution | Yes | The H3 resolution level (0-15) for binning. Default is 8. | |
| radius_meters | No | Optional search radius in metres around the location/bbox center. | |
| timeout_seconds | No | Overpass server query timeout in seconds. Default is 25. | |
| use_area_boundary | No | If true (default), uses exact OSM boundary polygon for named locations when available. |
Output Schema
| Name | Required | Description |
|---|---|---|
| complete | Yes | |
| warnings | Yes | |
| share_url | Yes | |
| hex_counts | Yes | |
| provenance | Yes | |
| resolution | Yes | |
| hex_geojson | Yes | |
| osm_area_id | No | |
| alternatives | No | |
| matched_place | No | |
| original_bbox | Yes | |
| total_elements | Yes | |
| active_hex_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds that results are plotted onto a 'shareable verification map', which hints at a persistent side effect not captured by the annotations, but it says nothing about Overpass timeout behaviour, query failures, or how many hotspots are retained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action (query + H3 binning) before the secondary output behaviour (hotspot plotting). No filler or redundant restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the oneOf location/bbox exclusivity is handled structurally by the schema. What remains thin is operational context around failure modes and the nature of the plotted map output, but overall the description is adequate for a seven-parameter read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter including query, resolution, bbox/location, radius_meters, timeout_seconds, and use_area_boundary is already documented in the schema. The description only echoes that resolution drives the binning and adds no format or default guidance beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names two concrete operations: executing an Overpass query and binning results into H3 hexagons at a resolution, plus plotting density hotspots. This is a specific verb+resource statement an agent can act on. It does not explicitly contrast with the sibling search_overpass or get_h3_indices, so differentiation is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the tool is for spatial density analysis rather than raw feature retrieval. There is no explicit statement of when to pick this over search_overpass (raw results) or get_h3_indices (index retrieval), and no prerequisites or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_routeARead-onlyIdempotent
Calculate real-world travel distance, duration, turn-by-turn summary, GeoJSON route geometry, and route bounding box between two locations or coordinate pairs using OpenStreetMap routing (FOSSGIS / OSRM, or configurable OSRM_API_URL). Draws the actual route path on the verification map and enforces rate limits (max 1 req/s).
| Name | Required | Description | Default |
|---|---|---|---|
| origin | Yes | Starting point as 'lat,lng' coordinates (e.g. '40.7128,-74.0060') or a natural-language place name (e.g. 'Times Square, NYC'). | |
| profile | No | Travel mode profile: 'driving' (car), 'walking' (foot), or 'cycling' (bicycle). Defaults to 'driving'. | |
| destination | Yes | Ending point as 'lat,lng' coordinates (e.g. '40.6413,-73.7781') or a natural-language place name (e.g. 'JFK Airport'). | |
| return_steps | No | If true, includes step-by-step road names and maneuver instructions. Defaults to false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| steps | No | |
| origin | Yes | |
| profile | Yes | |
| complete | Yes | |
| warnings | Yes | |
| share_url | Yes | |
| provenance | Yes | |
| route_bbox | Yes | |
| destination | Yes | |
| distance_km | Yes | |
| detour_factor | Yes | |
| route_geometry | Yes | |
| distance_meters | Yes | |
| initial_bearing | Yes | |
| duration_minutes | Yes | |
| duration_seconds | Yes | |
| straight_line_meters | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true and destructiveHint=false, so the safety profile is covered. The description goes beyond them with real operational detail: an external provider dependency (FOSSGIS/OSRM, overridable via OSRM_API_URL), a hard rate limit of max 1 req/s, and the side effect of drawing the path on the verification map. It stops short of describing failure behavior when a provider is unreachable or a place name fails to resolve.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the capability and outputs before the provider/rate-limit detail. Dense with little waste, though the trailing parenthetical about OSRM_API_URL and the map-drawing clause are secondary information that could be split or subordinated more cleanly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, and it correctly focuses on capability, data source, rate limits, and side effects. The main remaining gap for a 4-parameter open-world tool is failure and resolution behavior (what happens when a place name is ambiguous or the routing service errors), which the description leaves silent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including per-parameter docs for origin/destination formats, the profile enum, and return_steps, so the schema does the heavy lifting. The description adds only the notion that endpoints can be coordinates or place names and that turn-by-turn output exists, without adding format or edge-case detail beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource — 'Calculate real-world travel distance, duration, turn-by-turn summary, GeoJSON route geometry, and route bounding box' — and scopes it to 'between two locations or coordinate pairs'. It enumerates the outputs so an agent knows exactly what it gets, and no sibling tool (get_bounds, spatial_calc, search_overpass) covers routing, so the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the phrase 'between two locations or coordinate pairs' hints at routing use cases, and the rate-limit note constrains call frequency, but there is no explicit when-to-use, when-not-to-use, or pointer to an alternative sibling (e.g. spatial_calc for straight-line distance, reverse_geocode for resolving place names). An agent must infer the routing niche itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_boundsARead-onlyIdempotent
Get converted coordinates for a bounding box or natural-language location search (powered by Nominatim with configurable Photon & optional Mapbox fallbacks). Supports parsing WKT, GeoJSON, ogrinfo extent, Web Mercator tiles ('z/x/y'), single points ('lat,lng'), and raw coordinate strings, plus optional metric buffering.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), a single point ('lat,lng'), a Web Mercator tile ('z/x/y'), a WKT polygon/linestring/point, a GeoJSON payload, or an `ogrinfo` extent block. Either 'location' or 'bbox' MUST be provided. | |
| epsg | No | The projected EPSG code (e.g. '3857'). Defaults to '4326' (WGS84). Over 3,900 bundled projections; unknown codes are auto-fetched from epsg.io. | |
| zoom | No | The map zoom level (0-22) used to calculate the map tile coordinates for the centroid. Defaults to 15. | |
| format | No | Format of the output. Options: wkt, geojson-bbox, leaflet, overpass, ogc-bbox, kml, geojson-polygon, csv, stac-bbox. Default: csv. | |
| location | No | A text location to search for (e.g. 'New York City', 'Central Park'). Uses OpenStreetMap Nominatim (or configurable NOMINATIM_API_URL / PHOTON_API_URL / optional MAPBOX_ACCESS_TOKEN). Either 'location' or 'bbox' MUST be provided. | |
| precision | No | The number of decimal places to output coordinate strings as (defaults to 6). | |
| coord_order | No | Toggle between 'lng,lat' (default) and 'lat,lng' coordinate ordering in the formatted output. Useful for APIs that expect swapped coordinate orders. | |
| buffer_meters | No | Optional distance in meters to expand (positive) or shrink (negative) the bounding box in all directions. Ideal for creating a bounding box around a single point. |
Output Schema
| Name | Required | Description |
|---|---|---|
| epsg | Yes | |
| center | Yes | |
| format | Yes | |
| area_km2 | Yes | |
| complete | Yes | |
| warnings | Yes | |
| precision | Yes | |
| projected | Yes | |
| share_url | Yes | |
| dimensions | Yes | |
| provenance | Yes | |
| coord_order | Yes | |
| alternatives | No | |
| tile_indices | Yes | |
| matched_place | No | |
| original_wgs84 | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive) and openness, so the description's job is narrower and it delivers: it discloses the external dependency on Nominatim with configurable Photon/Mapbox fallbacks, and that unknown EPSG codes are auto-fetched from epsg.io — both network-facing behaviors an agent should know about. It does not mention latency, rate limits, or failure behavior when the geocoder misses.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single front-loaded sentence that leads with the primary capability and the two input modes, then the format list. It is dense and slightly run-on, and the format enumeration duplicates the bbox schema, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. Given the input schema, annotations, and output schema, the description supplies the remaining essentials: the external geocoding providers, the projection-source fallback, and the accepted geometry formats.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description restates the bbox input variants and 'optional metric buffering' (buffer_meters), but adds no syntax, defaults, or edge-case guidance beyond what the property descriptions already say; epsg, zoom, format, precision, and coord_order are untouched.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get converted coordinates') and names the two input modes it handles: a bounding box or a natural-language location search. An agent can tell this is a coordinate-conversion helper rather than a geocoder or route tool, though it never names a sibling (e.g. reverse_geocode) to draw the boundary explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the enumerated input formats (WKT, GeoJSON, ogrinfo extent, z/x/y tiles, 'lat,lng', raw strings) suggest when the tool fits, but there is no explicit 'use this when…' or 'use reverse_geocode instead when…' routing. With nine siblings including reverse_geocode and spatial_calc, the overlap remains for the agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_elevationARead-onlyIdempotent
Query terrain elevation in meters above sea level using the Open-Meteo 90m Copernicus DEM API (free for non-commercial use; commercial use requires a paid key or self-hosted ELEVATION_API_URL). Supports querying specific point coordinates OR sampling an N×N point grid across a bounding box to compute sample statistics (note: finite grid sampling over a 90m DEM reports sample statistics, not guaranteed area-wide true minimum, maximum, or slope).
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | A bounding box or point string to sample terrain elevation across. | |
| points | No | List of {lat, lng, label?} points to query elevation for (up to 100 points). | |
| location | No | A text location to sample elevation across (e.g. 'Mount Rainier', 'Denver'). | |
| grid_size | No | Grid dimension N (N x N samples, from 2 to 10) when sampling a bounding box. Defaults to 5 (25 sample points). |
Output Schema
| Name | Required | Description |
|---|---|---|
| bbox | Yes | |
| mode | Yes | |
| samples | Yes | |
| complete | Yes | |
| warnings | Yes | |
| share_url | Yes | |
| provenance | Yes | |
| sample_count | Yes | |
| sample_stats | Yes | |
| matched_place | No | |
| dem_resolution_meters | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, open-world), so the description is free to spend its words elsewhere — and it does: it discloses the licensing/auth constraint (free for non-commercial, paid key or self-hosted ELEVATION_API_URL otherwise) and, more importantly, that grid results are point-sample statistics, not guaranteed true extrema or slope. That caveat materially affects how an agent reports results. It doesn't mention rate limits or failure behavior for out-of-coverage coordinates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the core action and units before the licensing and sampling caveats. The nested parentheses are slightly heavy but every clause carries information the agent needs; nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and annotations carry the safety profile. The remaining gap is precedence: all four parameters are optional with three mutually alternative entry modes (points, bbox, location), and the description never states what happens if more than one is provided or what the fallback is — a real ambiguity for a zero-required-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents every parameter, which sets the baseline at 3. The description adds only the mode relationship (grid_size applies to bbox sampling) and the statistical meaning of those samples; it says nothing extra about how 'location' is resolved or what happens when multiple mode parameters are supplied together.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource with units and data provenance: 'Query terrain elevation in meters above sea level using the Open-Meteo 90m Copernicus DEM API', and names both operating modes (point coordinates vs N×N bbox grid). It doesn't explicitly contrast itself with any sibling, but none of the listed siblings (get_bounds, reverse_geocode, spatial_calc) overlap with elevation lookup, so misrouting risk is low.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'OR' framing tells the agent that point queries and grid sampling are alternative modes, and the parenthetical warns when grid sampling is the wrong basis for area-wide min/max/slope claims — genuine when-not guidance. It stops short of saying how to choose among the three entry parameters (points vs bbox vs location) or which takes precedence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_h3_indicesARead-onlyIdempotent
Get Uber H3 cell indices for a polygon (including interior holes), location boundary, or bounding box at a target resolution. When a WKT/GeoJSON polygon or named location boundary is provided, fills the exact polygon geometry (subtracting interior holes) rather than just its bounding rectangle.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT polygon (with optional holes), GeoJSON polygon/multipolygon, tile 'z/x/y', or ogrinfo extent. Either 'location' or 'bbox' MUST be provided. | |
| compact | No | Whether to return a compacted list of cells (mixing resolutions) to minimize response size. Defaults to false. | |
| location | No | A text location to search for (e.g. 'San Francisco'). Either 'location' or 'bbox' MUST be provided. | |
| resolution | Yes | The H3 resolution level, from 0 to 15. (e.g. 7) | |
| summary_only | No | If true, returns only cell count, sample cells, and map share URL without dumping thousands of cell IDs into context. Ideal for high resolutions. Defaults to false. | |
| return_geometry | No | If true, return GeoJSON FeatureCollection with hex boundary polygons in addition to cell IDs. Defaults to false. | |
| use_polygon_boundary | No | If true (default), fills the exact WKT/GeoJSON/OSM polygon boundary (including interior holes) instead of its rectangular bounding box when available. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cells | No | |
| compact | Yes | |
| geojson | No | |
| complete | Yes | |
| warnings | Yes | |
| share_url | Yes | |
| cell_count | Yes | |
| provenance | Yes | |
| resolution | Yes | |
| sample_cells | No | |
| summary_only | Yes | |
| original_bbox | Yes | |
| used_polygon_boundary | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive, and open-world behavior. Beyond that, the description usefully discloses that polygon and named-location inputs fill exact geometry including interior holes rather than only the bounding rectangle, which is relevant behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two front-loaded sentences with no filler. The core operation comes first, followed by the important geometry detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has seven parameters but full schema coverage, an output schema, and rich annotations. The description covers the core operation and the key polygon-hole behavior; only sibling differentiation is notably absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains bbox, location, resolution, compact, summary_only, return_geometry, and use_polygon_boundary. The description reinforces the polygon-versus-bbox behavior but adds little parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: get Uber H3 cell indices for a polygon, location boundary, or bounding box at a target resolution. It clearly identifies the operation but does not differentiate this tool from siblings such as aggregate_overpass_h3 or get_bounds.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by naming accepted geometry inputs and the target resolution, so an agent can infer when the tool applies. However, it gives no explicit when-to-use versus alternatives guidance or exclusions for sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_osm_tagsARead-onlyIdempotent
Discovery tool to look up the correct OpenStreetMap tags for any category. Uses built-in category index and live Taginfo API fallback to prevent tag hallucination.
| Name | Required | Description | Default |
|---|---|---|---|
| category | Yes | Category or keyword to look up (e.g. 'food', 'ev charging', 'gym', 'coworking', 'banks', 'dog park'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| tags | Yes | |
| source | Yes | |
| category | Yes | |
| complete | Yes | |
| warnings | Yes | |
| provenance | Yes | |
| recommendations_text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, open-world and non-destructive, so the safety profile is covered. The description adds real context beyond that: results come from a built-in category index with a live Taginfo API fallback, telling the agent to expect external network-dependent lookups and that this is the sanctioned source of tag truth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the tool's role and its data sources front-loaded. Nothing is repeated from the annotations or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and annotations carry the safety profile, leaving a simple one-parameter lookup. Minor omissions remain: behavior when a category is unknown, and whether the live API fallback affects latency or result variance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage and a single required parameter already exemplified in the schema ('food', 'ev charging', etc.), the schema does the work. The description only reinforces breadth ('any category') without adding format, matching, or normalization guidance beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: look up OpenStreetMap tags for a category, framed as a 'discovery tool'. That role contrasts implicitly with siblings like search_overpass (which runs queries) and reverse_geocode, though no sibling is named outright.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'For any category' implies the call context, and the anti-hallucination framing hints it should precede tag-dependent queries. There is no explicit when-not-to-use clause and no named alternative tool to route to instead, so the agent must infer the workflow position.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reverse_geocodeARead-onlyIdempotent
Reverse geocode latitude and longitude coordinates to discover context, place name, address components, and OSM details ('what is here?').
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | Latitude coordinate (-90 to 90). | |
| lng | Yes | Longitude coordinate (-180 to 180). | |
| zoom | No | Detail zoom level from 0 (country) to 18 (building/address). Defaults to 18. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bbox | Yes | |
| type | No | |
| class | No | |
| center | Yes | |
| osm_id | No | |
| address | Yes | |
| complete | Yes | |
| osm_type | No | |
| warnings | Yes | |
| share_url | Yes | |
| provenance | Yes | |
| matched_place | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld, and non-destructive, so the safety profile is covered. The description adds only the shape of the returned data, which is largely redundant with the existing output schema, and says nothing about rate limits, coverage gaps, or fallback behavior when no feature is found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the verb and resource first, then the output summary. The enumeration of return fields is slightly padded given an output schema already exists, but nothing is confusing or wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Parameters are fully documented, annotations cover the safety profile, and an output schema exists, so the description need not explain return values. The main remaining gap is sibling differentiation, which matters here because search_overpass and get_bounds operate near this query space.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including coordinate ranges and the zoom scale (0=country to 18=building/address). The description mentions only lat/lng and adds no meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reverse geocode latitude and longitude coordinates') and enumerates what it yields (place name, address components, OSM details). It is clear on its own, but it never distinguishes itself from siblings like search_overpass, which could also answer a 'what is here' question.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'what is here?' implies the query type this tool answers, giving implicit usage context. There is no explicit when-to-use statement, no prerequisites, and no routing to alternatives such as search_overpass for tag-based lookups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_overpassARead-onlyIdempotent
Execute an Overpass QL query to find POIs, roads, or other OSM features within an admin boundary area, bounding box, or radius. The server wraps your query in spatial filters, detects Overpass runtime errors, and returns structured JSON with provenance, completeness metadata, distance calculations, and a map link.
SEARCH MODES:
Location / Admin Area: when 'location' resolves to an OSM boundary polygon (e.g. 'Manhattan', 'Seattle'), searches inside exact boundary polygon.
Bounding box (default): searches a rectangular area.
Circle: searches within an exact radius when 'radius_meters' is provided.
Fast Count: set 'count_only: true' to get instant element counts without downloading full element payloads.
COMMON TAG EXAMPLES:
Restaurants:
nwr["amenity"="restaurant"]Pizza:
nwr["amenity"="fast_food"]["cuisine"="pizza"]Supermarkets:
nwr["shop"="supermarket"]Parks:
nwr["leisure"="park"]Hospitals:
nwr["amenity"="hospital"]EV Charging:
nwr["amenity"="charging_station"]Gyms:
nwr["leisure"="fitness_centre"]Banks:
nwr["amenity"="bank"]
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT, GeoJSON, or ogrinfo extent. Either 'location' or 'bbox' MUST be provided. | |
| limit | No | Maximum number of elements to return per page. Default is 100. | |
| query | Yes | The Overpass QL core query. Example: `node["amenity"="cafe"]` or `nwr["leisure"="park"]`. Multi-statement queries supported (e.g. `nwr["office"="coworking"]; nwr["amenity"="coworking_space"]`). DO NOT include spatial filters or output directives. | |
| offset | No | Pagination offset for retrieving subsequent pages of results. Default is 0. | |
| location | No | A text location to search for (e.g. 'Manhattan', 'San Francisco'). Either 'location' or 'bbox' MUST be provided. | |
| count_only | No | If true, executes an ultra-fast Overpass 'out count;' query and returns total counts (nodes, ways, relations, total) without downloading individual features. Defaults to false. | |
| radius_meters | No | Search radius in metres. Enables circle mode — use ONLY when explicit distance is specified ('2km' → 2000). | |
| return_geometry | No | If true, returns full geometry (polygon/polyline) for ways and relations instead of center point. Defaults to false. | |
| timeout_seconds | No | Overpass server query timeout in seconds. Default is 25. | |
| sort_by_distance | No | If true, sorts returned elements by distance from origin/center. Enabled by default for circle mode and point locations. | |
| use_area_boundary | No | If true (default), uses exact OSM administrative boundary polygon for named locations when available, avoiding bounding box collapse. |
Output Schema
| Name | Required | Description |
|---|---|---|
| limit | No | |
| osm3s | No | |
| counts | No | |
| offset | No | |
| complete | Yes | |
| elements | No | |
| has_more | No | |
| warnings | Yes | |
| generator | No | |
| share_url | Yes | |
| truncated | No | |
| count_only | Yes | |
| provenance | Yes | |
| next_offset | No | |
| osm_area_id | No | |
| search_mode | Yes | |
| total_count | No | |
| alternatives | No | |
| distance_from | No | |
| matched_place | No | |
| returned_count | No | |
| pagination_hint | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld/non-destructive, yet the description still adds substantive behavior: the server wraps the query in spatial filters, detects Overpass runtime errors, and returns provenance, completeness metadata, distance calculations, and a map link. The note that the query is auto-wrapped with spatial filters materially changes how an agent should construct input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and scope, then organized under two clear headers, with no filler sentences. The eight common tag examples are useful for syntax learning but become repetitive after the first three, which all follow the same nwr["key"="value"] pattern.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter, open-world query tool with a full output schema and complete annotation coverage, this is close to complete: modes, query construction rules, count fast-path, and return content are all covered. Minor gaps remain around pagination behavior across pages and what a partial/failed query looks like to the caller.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: the 'DO NOT include spatial filters or output directives' constraint on query, the '2km → 2000' unit interpretation for radius_meters, and the note that sort_by_distance is on by default for circle mode and point locations. The tag examples also teach valid Overpass QL syntax that the schema only gestures at.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb and resource ('Execute an Overpass QL query to find POIs, roads, or other OSM features') plus the three supported spatial scopes. It is unambiguous what the tool does, but it never explicitly distinguishes itself from the closest sibling, aggregate_overpass_h3, which presumably wraps the same data source for H3 aggregation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The SEARCH MODES block gives clear conditional routing among location, bbox, circle, and count_only, and radius_meters carries an explicit 'use ONLY when explicit distance is specified' exclusion. What is missing is any guidance on when to prefer a sibling tool (e.g. aggregate_overpass_h3 for aggregation, list_osm_tags for tag discovery) over this raw search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spatial_calcARead-onlyIdempotent
Perform deterministic offline geometric calculations on bounding boxes, points, and polygons (with holes, zero network calls): 'relation' (intersects, contains, overlap area %, union & intersection bbox between two geometries), 'point_in_geometry' (check if a point is inside a bbox or WKT/GeoJSON polygon respecting interior holes), 'distance_bearing' (exact Haversine distance, initial compass bearing, and midpoint between two points), or 'split_grid' (subdivide a bbox into an N x M grid of sub-bboxes for chunked queries).
| Name | Required | Description | Default |
|---|---|---|---|
| cols | No | Number of longitude columns for 'split_grid' (1-20, default 2). | |
| rows | No | Number of latitude rows for 'split_grid' (1-20, default 2). | |
| point | No | Point coordinates 'lat,lng' to test in 'point_in_geometry'. | |
| bbox_a | Yes | First geometry / bounding box (for 'relation', 'point_in_geometry', 'split_grid') or origin point 'lat,lng' (for 'distance_bearing'). | |
| bbox_b | No | Second geometry / bounding box (for 'relation') or destination point 'lat,lng' (for 'distance_bearing'). | |
| operation | Yes | The geometric operation to perform. |
Output Schema
| Name | Required | Description |
|---|---|---|
| to | No | |
| bbox | No | |
| cols | No | |
| from | No | |
| rows | No | |
| cells | No | |
| point | No | |
| inside | No | |
| complete | Yes | |
| midpoint | No | |
| warnings | Yes | |
| operation | Yes | |
| share_url | Yes | |
| area_a_km2 | No | |
| area_b_km2 | No | |
| intersects | No | |
| provenance | Yes | |
| union_bbox | No | |
| distance_km | No | |
| inside_bbox | No | |
| target_bbox | No | |
| total_cells | No | |
| a_contains_b | No | |
| b_contains_a | No | |
| original_bbox | No | |
| inside_polygon | No | |
| union_area_km2 | No | |
| bearing_degrees | No | |
| distance_meters | No | |
| intersection_bbox | No | |
| cardinal_direction | No | |
| overlap_percent_of_a | No | |
| overlap_percent_of_b | No | |
| intersection_area_km2 | No | |
| centroid_distance_meters | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuine behavioral context beyond them: deterministic results, no network access, interior holes respected in containment tests, and grid bounds of 1-20 with default 2. It does not describe failure modes for malformed WKT or out-of-range rows/cols, but the added disclosure is substantive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then a single structured enumeration of the four operations. Dense with parenthetical detail but nearly every clause carries operational information; the one-sentence mega-structure is slightly harder to scan than a short bulleted layout would be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and all four operation modes plus their parameter roles are covered. What remains thin is edge-case behavior (invalid geometry input, behavior when bbox_a is a polygon for split_grid), which keeps it just short of fully complete for a six-parameter multi-mode tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description earns above it by clarifying geometry formats the schema leaves generic ('bbox or WKT/GeoJSON polygon', 'lat,lng' origin/destination) and by tying cols/rows to the split_grid subdivision semantics. The mapping of which parameter is consumed by which operation is spelled out in prose as well as schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('deterministic offline geometric calculations on bounding boxes, points, and polygons') and then enumerates the four operations with their outputs (overlap area %, union & intersection bbox, Haversine distance, N x M grid). The 'zero network calls' clause separates it from network-dependent siblings like reverse_geocode and search_overpass.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each operation name is paired with the condition that selects it (use 'relation' for two-geometry comparison, 'point_in_geometry' for point-in-polygon with holes, 'distance_bearing' for point pairs, 'split_grid' for chunked queries), which is effectively mode-selection guidance. It stops short of naming an explicit sibling alternative or stating when not to use it, so it is clear context rather than full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v1.5.0- Changed
aggregate_overpass_h34 fields changed- added
Input schema / properties / radius_metersAdded value: +{ + "description": "Optional search radius in metres around the location/bbox center.", + "type": "number" +} - added
Input schema / properties / timeout_secondsAdded value: +{ + "description": "Overpass server query timeout in seconds. Default is 25.", + "type": "number" +} - added
Input schema / properties / use_area_boundaryAdded value: +{ + "description": "If true (default), uses exact OSM boundary polygon for named locations when available.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "active_hex_count": { + "type": "number" + }, + "alternatives": { + "items": { + "type": "object" + }, + "type": "array" + }, + "complete": { + "type": "boolean" + }, + "hex_counts": { + "type": "object" + }, + "hex_geojson": { + "type": "object" + }, + "matched_place": { + "type": "string" + }, + "original_bbox": { + "properties": { + "lat1": { + "type": "number" + }, + "lat2": { + "type": "number" + }, + "lng1": { + "type": "number" + }, + "lng2": { + "type": "number" + } + }, + "required": [ + "lat1", + "lng1", + "lat2", + "lng2" + ], + "type": "object" + }, + "osm_area_id": { + "type": "number" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "resolution": { + "type": "number" + }, + "share_url": { + "type": "string" + }, + "total_elements": { + "type": "number" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "resolution", + "total_elements", + "active_hex_count", + "hex_counts", + "hex_geojson", + "original_bbox", + "share_url", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Added
calculate_route - Changed
generate_share_url2 fields changed- changed
Input schema / properties / bbox / descriptionPrevious value: -"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT, GeoJSON, or ogrinfo extent."New value: +"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT, GeoJSON, tile 'z/x/y', or ogrinfo extent." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "bbox": { + "properties": { + "lat1": { + "type": "number" + }, + "lat2": { + "type": "number" + }, + "lng1": { + "type": "number" + }, + "lng2": { + "type": "number" + } + }, + "required": [ + "lat1", + "lng1", + "lat2", + "lng2" + ], + "type": "object" + }, + "complete": { + "type": "boolean" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "share_url": { + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "bbox", + "share_url", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Changed
get_bounds4 fields changed- changed
Input schema / properties / bbox / descriptionPrevious value: -"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), a WKT polygon/linestring/point, a GeoJSON payload, or an `ogrinfo` extent block. The Minimum Bounding Rectangle (MBR) encapsulating the geometry will be extracted. Either 'location' or 'bbox' MUST be provided."New value: +"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), a single point ('lat,lng'), a Web Mercator tile ('z/x/y'), a WKT polygon/linestring/point, a GeoJSON payload, or an `ogrinfo` extent block. Either 'location' or 'bbox' MUST be provided." - added
Input schema / properties / buffer_metersAdded value: +{ + "description": "Optional distance in meters to expand (positive) or shrink (negative) the bounding box in all directions. Ideal for creating a bounding box around a single point.", + "type": "number" +} - changed
Input schema / properties / location / descriptionPrevious value: -"A text location to search for (e.g. 'New York City'). Requires MAPBOX_ACCESS_TOKEN env var. Either 'location' or 'bbox' MUST be provided."New value: +"A text location to search for (e.g. 'New York City', 'Central Park'). Uses OpenStreetMap Nominatim (or configurable NOMINATIM_API_URL / PHOTON_API_URL / optional MAPBOX_ACCESS_TOKEN). Either 'location' or 'bbox' MUST be provided." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "alternatives": { + "items": { + "type": "object" + }, + "type": "array" + }, + "area_km2": { + "type": "number" + }, + "center": { + "properties": { + "lat": { + "type": "number" + }, + "lng": { + "type": "number" + } + }, + "required": [ + "lat", + "lng" + ], + "type": "object" + }, + "complete": { + "type": "boolean" + }, + "coord_order": { + "type": "string" + }, + "dimensions": { + "properties": { + "height_km": { + "type": "number" + }, + "width_km": { + "type": "number" + } + }, + "required": [ + "width_km", + "height_km" + ], + "type": "object" + }, + "epsg": { + "type": "string" + }, + "format": { + "type": "string" + }, + "matched_place": { + "type": "string" + }, + "original_wgs84": { + "properties": { + "lat1": { + "type": "number" + }, + "lat2": { + "type": "number" + }, + "lng1": { + "type": "number" + }, + "lng2": { + "type": "number" + } + }, + "required": [ + "lat1", + "lng1", + "lat2", + "lng2" + ], + "type": "object" + }, + "precision": { + "type": "number" + }, + "projected": { + "properties": { + "xmax": { + "type": "number" + }, + "xmin": { + "type": "number" + }, + "ymax": { + "type": "number" + }, + "ymin": { + "type": "number" + } + }, + "required": [ + "xmin", + "ymin", + "xmax", + "ymax" + ], + "type": "object" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "share_url": { + "type": "string" + }, + "tile_indices": { + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "z": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "z" + ], + "type": "object" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "original_wgs84", + "projected", + "center", + "tile_indices", + "epsg", + "format", + "coord_order", + "precision", + "area_km2", + "dimensions", + "share_url", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Added
get_elevation - Changed
get_h3_indices5 fields changed- changed
Input schema / properties / bbox / descriptionPrevious value: -"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT, GeoJSON, or ogrinfo extent. Either 'location' or 'bbox' MUST be provided."New value: +"The geometry to parse. Can be a raw bounding box string ('lat1,lng1,lat2,lng2'), WKT polygon (with optional holes), GeoJSON polygon/multipolygon, tile 'z/x/y', or ogrinfo extent. Either 'location' or 'bbox' MUST be provided." - changed
Input schema / properties / location / descriptionPrevious value: -"A text location to search for (e.g. 'San Francisco'). Requires MAPBOX_ACCESS_TOKEN env var. Either 'location' or 'bbox' MUST be provided."New value: +"A text location to search for (e.g. 'San Francisco'). Either 'location' or 'bbox' MUST be provided." - added
Input schema / properties / summary_onlyAdded value: +{ + "description": "If true, returns only cell count, sample cells, and map share URL without dumping thousands of cell IDs into context. Ideal for high resolutions. Defaults to false.", + "type": "boolean" +} - added
Input schema / properties / use_polygon_boundaryAdded value: +{ + "description": "If true (default), fills the exact WKT/GeoJSON/OSM polygon boundary (including interior holes) instead of its rectangular bounding box when available.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "cell_count": { + "type": "number" + }, + "cells": { + "items": { + "type": "string" + }, + "type": "array" + }, + "compact": { + "type": "boolean" + }, + "complete": { + "type": "boolean" + }, + "geojson": { + "type": "object" + }, + "original_bbox": { + "properties": { + "lat1": { + "type": "number" + }, + "lat2": { + "type": "number" + }, + "lng1": { + "type": "number" + }, + "lng2": { + "type": "number" + } + }, + "required": [ + "lat1", + "lng1", + "lat2", + "lng2" + ], + "type": "object" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "resolution": { + "type": "number" + }, + "sample_cells": { + "items": { + "type": "string" + }, + "type": "array" + }, + "share_url": { + "type": "string" + }, + "summary_only": { + "type": "boolean" + }, + "used_polygon_boundary": { + "type": "boolean" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "resolution", + "compact", + "summary_only", + "used_polygon_boundary", + "cell_count", + "original_bbox", + "share_url", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Changed
list_osm_tags2 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Broad category to look up (e.g. 'food', 'health', 'transport', 'leisure', 'retail')."New value: +"Category or keyword to look up (e.g. 'food', 'ev charging', 'gym', 'coworking', 'banks', 'dog park')." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "category": { + "type": "string" + }, + "complete": { + "type": "boolean" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "recommendations_text": { + "type": "string" + }, + "source": { + "type": "string" + }, + "tags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "category", + "source", + "tags", + "recommendations_text", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Added
reverse_geocode - Changed
search_overpass11 fields changed- added
Input schema / properties / count_onlyAdded value: +{ + "description": "If true, executes an ultra-fast Overpass 'out count;' query and returns total counts (nodes, ways, relations, total) without downloading individual features. Defaults to false.", + "type": "boolean" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of elements to return. Default is 100. Increase if you need more results."New value: +"Maximum number of elements to return per page. Default is 100." - changed
Input schema / properties / location / descriptionPrevious value: -"A text location to search for (e.g. 'San Francisco', 'JFK Airport'). Requires MAPBOX_ACCESS_TOKEN env var. Either 'location' or 'bbox' MUST be provided."New value: +"A text location to search for (e.g. 'Manhattan', 'San Francisco'). Either 'location' or 'bbox' MUST be provided." - added
Input schema / properties / offsetAdded value: +{ + "description": "Pagination offset for retrieving subsequent pages of results. Default is 0.", + "type": "number" +} - changed
Input schema / properties / query / descriptionPrevious value: -"The Overpass QL core query. Example: `node[\"amenity\"=\"cafe\"]` or `nwr[\"leisure\"=\"park\"]`. DO NOT include spatial filters, bounding box, or output directives — the server handles those automatically."New value: +"The Overpass QL core query. Example: `node[\"amenity\"=\"cafe\"]` or `nwr[\"leisure\"=\"park\"]`. Multi-statement queries supported (e.g. `nwr[\"office\"=\"coworking\"]; nwr[\"amenity\"=\"coworking_space\"]`). DO NOT include spatial filters or output directives." - changed
Input schema / properties / radius_meters / descriptionPrevious value: -"Search radius in metres. Enables circle mode — use ONLY when the user specifies an explicit distance (e.g. '2km' → 2000, '500 metres' → 500, '1 mile' → 1609). Omit entirely for area/region queries or vague terms like 'near'."New value: +"Search radius in metres. Enables circle mode — use ONLY when explicit distance is specified ('2km' → 2000)." - added
Input schema / properties / return_geometryAdded value: +{ + "description": "If true, returns full geometry (polygon/polyline) for ways and relations instead of center point. Defaults to false.", + "type": "boolean" +} - added
Input schema / properties / sort_by_distanceAdded value: +{ + "description": "If true, sorts returned elements by distance from origin/center. Enabled by default for circle mode and point locations.", + "type": "boolean" +} - added
Input schema / properties / timeout_secondsAdded value: +{ + "description": "Overpass server query timeout in seconds. Default is 25.", + "type": "number" +} - added
Input schema / properties / use_area_boundaryAdded value: +{ + "description": "If true (default), uses exact OSM administrative boundary polygon for named locations when available, avoiding bounding box collapse.", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "alternatives": { + "items": { + "type": "object" + }, + "type": "array" + }, + "complete": { + "type": "boolean" + }, + "count_only": { + "type": "boolean" + }, + "counts": { + "properties": { + "nodes": { + "type": "number" + }, + "relations": { + "type": "number" + }, + "total": { + "type": "number" + }, + "ways": { + "type": "number" + } + }, + "type": "object" + }, + "distance_from": { + "type": "object" + }, + "elements": { + "items": { + "type": "object" + }, + "type": "array" + }, + "generator": { + "type": "string" + }, + "has_more": { + "type": "boolean" + }, + "limit": { + "type": "number" + }, + "matched_place": { + "type": "string" + }, + "next_offset": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "osm3s": { + "type": "object" + }, + "osm_area_id": { + "type": "number" + }, + "pagination_hint": { + "type": "string" + }, + "provenance": { + "properties": { + "attribution": { + "type": "string" + }, + "cache_age_ms": { + "type": "number" + }, + "cached": { + "type": "boolean" + }, + "data_timestamp": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "usage_policy": { + "type": "string" + } + }, + "required": [ + "provider", + "data_timestamp", + "cached", + "cache_age_ms" + ], + "type": "object" + }, + "returned_count": { + "type": "number" + }, + "search_mode": { + "type": "string" + }, + "share_url": { + "type": "string" + }, + "total_count": { + "type": "number" + }, + "truncated": { + "type": "boolean" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "search_mode", + "count_only", + "share_url", + "provenance", + "complete", + "warnings" + ], + "type": "object" +}
- Added
spatial_calc
1 tool update
v1.2.5- Changed
search_overpass4 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of elements to return. Helps prevent enormous JSON responses. Default is 100. Set to a higher number if you need more results."New value: +"Maximum number of elements to return. Default is 100. Increase if you need more results." - changed
Input schema / properties / location / descriptionPrevious value: -"A text location to search for (e.g. 'San Francisco'). Requires MAPBOX_ACCESS_TOKEN env var. Either 'location' or 'bbox' MUST be provided."New value: +"A text location to search for (e.g. 'San Francisco', 'JFK Airport'). Requires MAPBOX_ACCESS_TOKEN env var. Either 'location' or 'bbox' MUST be provided." - changed
Input schema / properties / query / descriptionPrevious value: -"The Overpass QL core query. Example: `node[\"amenity\"=\"cafe\"]` or `nwr[\"leisure\"=\"park\"]`. DO NOT include the bounding box `(S,W,N,E)` or output format (`out json`), the server handles that automatically."New value: +"The Overpass QL core query. Example: `node[\"amenity\"=\"cafe\"]` or `nwr[\"leisure\"=\"park\"]`. DO NOT include spatial filters, bounding box, or output directives — the server handles those automatically." - added
Input schema / properties / radius_metersAdded value: +{ + "description": "Search radius in metres. Enables circle mode — use ONLY when the user specifies an explicit distance (e.g. '2km' → 2000, '500 metres' → 500, '1 mile' → 1609). Omit entirely for area/region queries or vague terms like 'near'.", + "type": "number" +}
6 tool updates
v1.2.4- First observed
aggregate_overpass_h3 - First observed
generate_share_url - First observed
get_bounds - First observed
get_h3_indices - First observed
list_osm_tags - First observed
search_overpass
TDQS
Scored across 10 tools
Most tools target clearly distinct operations (geocoding, reverse geocoding, H3 indexing, routing, elevation, share URLs). The main overlap is between search_overpass and aggregate_overpass_h3, which share the same Overpass query surface and differ only by H3 binning, and spatial_calc bundles four disparate modes into one tool. Descriptions do enough to steer selection, but these boundaries are the weak spots.
Nine of ten names follow a predictable verb_noun pattern (get_h3_indices, get_bounds, search_overpass, list_osm_tags, calculate_route, get_elevation, generate_share_url). The exceptions are reverse_geocode (verb-first but noun-shaped) and spatial_calc (noun-only), both readable but minor deviations from the dominant convention.
Ten tools is well within the sweet spot and each one maps to a distinct geospatial capability. No tool feels redundant enough to remove, and the surface is not padded with trivial variants.
The surface covers the full stateless geospatial workflow: coordinate parsing/forward geocoding, reverse geocoding, tag discovery, POI search, density aggregation, H3 indexing, routing, elevation, offline geometry, and map sharing. Gaps are minor — no batch/bulk geocoding, isochrone/route-matrix operations, or explicit GeoJSON export are present, but agents can work around these via existing tools.
Maintenance
Related MCP Connectors
Routing, geocoding, places, matrix and map tools for location-aware AI workflows.
GIS tools for AI agents: 65 free tools + 8 paid (hazard/site-scouting/GeoJSON export)
Geocoding, routing, isochrones, traffic, weather, and place search for AI agents. 19 MCP tools.
13 privacy-first network, auth & web tools for AI agents — no API key, 60 req/min free.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAI agents hallucinate math. Euclid fixes that. Connect once and give your agent 10 deterministic tools: arithmetic, unit conversion, statistics, datetime, finance, regex, color, encoding, validation, and geospatial. Same input, same output, every time.2-

Mapbox MCP Serverofficial
AlicenseAqualityAmaintenanceProvides geospatial intelligence to AI agents through Mapbox APIs, enabling geocoding, routing, POI search, map images, and offline spatial calculations.286,987 npm366MIT- AlicenseAqualityDmaintenanceGeospatial API tools for AI agents — geocoding, reverse geocoding, routing, isochrone, distance matrix, static maps, H3 hexagons, elevation, GPS map-matching, point-in-polygon, address normalisation, timezone lookup, and batch geocoding. Built on OpenStreetMap infrastructure. Cost-effective alternative to Google Maps API.1839 npmMIT

Magic Lane MCP Serverofficial
AlicenseBqualityCmaintenanceEnables AI agents to become geospatially intelligent assistants with tools for location search, smart routing, round trip planning, reverse geocoding, isochrone analysis, route visualization, geofence management, and interactive map display.817 npm7Apache 2.0