Verifiable geospatial tools: distances, topology, isochrones, Overture Maps, with sources.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Exact geodesic distance between two places or geometries on the WGS84 ellipsoid. Use for any "how far" question instead of estimating. For NAMED places pass place_a and place_b; the server geocodes them, so never type coordinates for a place yourself. Use point_a/point_b only for coordinates the user gave or another tool returned. For lines and polygons the distance is between their nearest points. Returns metres and kilometres.
A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred)
A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred)
A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]}; only for coordinates the user gave or a tool returned
A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]}; only for coordinates the user gave or a tool returned
Exact geodesic distance between two places or geometries on the WGS84 ellipsoid. Use for any "how far" question instead of estimating. For NAMED places pass place_a and place_b; the server geocodes them, so never type coordinates for a place yourself. Use point_a/point_b only for coordinates the user gave or another tool returned. For lines and polygons the distance is between their nearest points. Returns metres and kilometres.
| Argument | Type | Description |
|---|---|---|
| place_a | any | A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred) |
| place_b | any | A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred) |
| point_a | any | A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]}; only for coordinates the user gave or a tool returned |
| point_b | any | A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]}; only for coordinates the user gave or a tool returned |
{
"type": "object",
"title": "calculate_distanceArguments",
"properties": {
"place_a": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
],
"title": "Place A",
"default": null,
"description": "A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred)"
},
"place_b": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
],
"title": "Place B",
"default": null,
"description": "A place NAME, e.g. 'Adelaide Oval'; geocoded on the server (preferred)"
},
"point_a": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Point A",
"default": null,
"description": "A GeoJSON geometry, e.g. {\"type\": \"Point\", \"coordinates\": [lon, lat]}; only for coordinates the user gave or a tool returned"
},
"point_b": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Point B",
"default": null,
"description": "A GeoJSON geometry, e.g. {\"type\": \"Point\", \"coordinates\": [lon, lat]}; only for coordinates the user gave or a tool returned"
}
}
}Ground-truth topology: does geometry_a <relationship> geometry_b? Use instead of guessing containment, overlap or adjacency. Invalid geometries (for example self-intersecting polygons) are refused with the reason.
| Argument | Type | Description |
|---|---|---|
| geometry_a* | object | A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]} |
| geometry_b* | object | A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]} |
| relationship* | string |
{
"type": "object",
"title": "check_spatial_relationshipArguments",
"required": [
"geometry_a",
"geometry_b",
"relationship"
],
"properties": {
"geometry_a": {
"type": "object",
"title": "Geometry A",
"description": "A GeoJSON geometry, e.g. {\"type\": \"Point\", \"coordinates\": [lon, lat]}",
"additionalProperties": true
},
"geometry_b": {
"type": "object",
"title": "Geometry B",
"description": "A GeoJSON geometry, e.g. {\"type\": \"Point\", \"coordinates\": [lon, lat]}",
"additionalProperties": true
},
"relationship": {
"enum": [
"contains",
"intersects",
"within",
"touches",
"crosses",
"overlaps",
"disjoint"
],
"type": "string",
"title": "Relationship"
}
}
}Find coordinates for an address or place name (OpenStreetMap Nominatim). Check `geospark.warnings` for ambiguous names (e.g. "Springfield") and ask the user which one they mean, or add a region.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query* | string | Address or place name |
{
"type": "object",
"title": "geocodeArguments",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"title": "Limit",
"default": 5,
"maximum": 10,
"minimum": 1
},
"query": {
"type": "string",
"title": "Query",
"maxLength": 500,
"minLength": 1,
"description": "Address or place name"
}
}
}Satellite active-fire detections near a point (NASA FIRMS; the server needs a FIRMS_MAP_KEY).
| Argument | Type | Description |
|---|---|---|
| days | integer | |
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "get_active_firesArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"days": {
"type": "integer",
"title": "Days",
"default": 1,
"maximum": 2,
"minimum": 1
},
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Latest PM2.5, NO2, O3 from the nearest monitoring stations (OpenAQ; the server needs an OPENAQ_API_KEY), with each station's data licence.
| Argument | Type | Description |
|---|---|---|
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "get_air_qualityArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Ground elevation in metres (Copernicus GLO-30, Open Elevation fallback), with its vertical datum and accuracy.
| Argument | Type | Description |
|---|---|---|
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "get_elevationArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Current weather and a daily forecast for a point (Open-Meteo, no key needed).
| Argument | Type | Description |
|---|---|---|
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
| forecast_days | integer |
{
"type": "object",
"title": "get_weatherArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
},
"forecast_days": {
"type": "integer",
"title": "Forecast Days",
"default": 3,
"maximum": 16,
"minimum": 1
}
}
}Where can you get to from a point within N minutes on foot, by bike or by car? Returns one polygon per contour with its geodesic area (Valhalla over OpenStreetMap).
| Argument | Type | Description |
|---|---|---|
| mode | string | |
| minutes | array | Contour times, 1-60 |
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "isochroneArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"mode": {
"enum": [
"walk",
"bike",
"drive"
],
"type": "string",
"title": "Mode",
"default": "walk"
},
"minutes": {
"type": "array",
"items": {
"type": "integer"
},
"title": "Minutes",
"default": [
10
],
"maxItems": 4,
"minItems": 1,
"description": "Contour times, 1-60"
},
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}A dossier for a place: address, elevation, weather, and nearby amenities with exact distances, as a GeoJSON map layer listing every data source used. Takes ~10-30 s.
| Argument | Type | Description |
|---|---|---|
| location* | string | Place to analyse |
| radius_m | number |
{
"type": "object",
"title": "location_reportArguments",
"required": [
"location"
],
"properties": {
"location": {
"type": "string",
"title": "Location",
"maxLength": 500,
"minLength": 1,
"description": "Place to analyse"
},
"radius_m": {
"type": "number",
"title": "Radius M",
"default": 1000,
"maximum": 10000,
"exclusiveMinimum": 0
}
}
}Open global map data from Overture Maps, no API key: points of interest (with categories), building footprints (height, floors, geodesic footprint area), road and path segments (geodesic length), or `divisions`, the administrative areas containing the point (country, region, city, neighbourhood). Results are nearest first, with distances in metres. Can take 5-20 s on a cold cache.
| Argument | Type | Description |
|---|---|---|
| limit | any | |
| theme* | string | |
| category | any | Places only, e.g. 'cafe' |
| latitude* | number | Latitude in degrees (WGS84) |
| radius_m | number | Search radius in metres |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "overture_featuresArguments",
"required": [
"theme",
"latitude",
"longitude"
],
"properties": {
"limit": {
"anyOf": [
{
"type": "integer",
"maximum": 2000,
"minimum": 1
},
{
"type": "null"
}
],
"title": "Limit",
"default": null
},
"theme": {
"enum": [
"places",
"buildings",
"transportation",
"divisions"
],
"type": "string",
"title": "Theme"
},
"category": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
],
"title": "Category",
"default": null,
"description": "Places only, e.g. 'cafe'"
},
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"radius_m": {
"type": "number",
"title": "Radius M",
"default": 300,
"maximum": 2000,
"description": "Search radius in metres",
"exclusiveMinimum": 0
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Find the address or place at a coordinate (OpenStreetMap Nominatim).
| Argument | Type | Description |
|---|---|---|
| latitude* | number | Latitude in degrees (WGS84) |
| longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "reverse_geocodeArguments",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"title": "Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"longitude": {
"type": "number",
"title": "Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Driving route between two points (OSRM over OpenStreetMap): line geometry, distance in metres and duration in seconds.
| Argument | Type | Description |
|---|---|---|
| to_latitude* | number | Latitude in degrees (WGS84) |
| to_longitude* | number | Longitude in degrees (WGS84) |
| from_latitude* | number | Latitude in degrees (WGS84) |
| from_longitude* | number | Longitude in degrees (WGS84) |
{
"type": "object",
"title": "routeArguments",
"required": [
"from_latitude",
"from_longitude",
"to_latitude",
"to_longitude"
],
"properties": {
"to_latitude": {
"type": "number",
"title": "To Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"to_longitude": {
"type": "number",
"title": "To Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
},
"from_latitude": {
"type": "number",
"title": "From Latitude",
"maximum": 90,
"minimum": -90,
"description": "Latitude in degrees (WGS84)"
},
"from_longitude": {
"type": "number",
"title": "From Longitude",
"maximum": 180,
"minimum": -180,
"description": "Longitude in degrees (WGS84)"
}
}
}Rank candidate sites in an area by geodesic distance to amenities you want nearby and away from ones to avoid (OpenStreetMap data). Takes ~10-30 s.
| Argument | Type | Description |
|---|---|---|
| near | array | Amenity types to be close to |
| avoid | array | Amenity types to stay away from |
| within* | string | City or neighbourhood |
| radius_m | number | |
| facility_type | string |
{
"type": "object",
"title": "select_siteArguments",
"required": [
"within"
],
"properties": {
"near": {
"type": "array",
"items": {
"type": "string"
},
"title": "Near",
"default": [],
"maxItems": 10,
"description": "Amenity types to be close to"
},
"avoid": {
"type": "array",
"items": {
"type": "string"
},
"title": "Avoid",
"default": [],
"maxItems": 10,
"description": "Amenity types to stay away from"
},
"within": {
"type": "string",
"title": "Within",
"maxLength": 500,
"minLength": 1,
"description": "City or neighbourhood"
},
"radius_m": {
"type": "number",
"title": "Radius M",
"default": 3000,
"maximum": 10000,
"exclusiveMinimum": 0
},
"facility_type": {
"type": "string",
"title": "Facility Type",
"default": "restaurant",
"maxLength": 100
}
}
}Compute a buffer (shape-preserving, metres), geodesic area or length, centroid or convex hull. Returns the resulting geometry as GeoJSON with its measurements and units.
| Argument | Type | Description |
|---|---|---|
| geometry* | object | A GeoJSON geometry, e.g. {"type": "Point", "coordinates": [lon, lat]} |
| radius_m | any | Buffer radius in metres |
| operation* | string |
{
"type": "object",
"title": "spatial_operationArguments",
"required": [
"operation",
"geometry"
],
"properties": {
"geometry": {
"type": "object",
"title": "Geometry",
"description": "A GeoJSON geometry, e.g. {\"type\": \"Point\", \"coordinates\": [lon, lat]}",
"additionalProperties": true
},
"radius_m": {
"anyOf": [
{
"type": "number",
"maximum": 100000,
"minimum": 0
},
{
"type": "null"
}
],
"title": "Radius M",
"default": null,
"description": "Buffer radius in metres"
},
"operation": {
"enum": [
"buffer",
"area",
"length",
"centroid",
"convex_hull"
],
"type": "string",
"title": "Operation"
}
}
}Network travel time (minutes) and distance (metres) from each origin to each destination. Note: points here are [latitude, longitude] pairs.
| Argument | Type | Description |
|---|---|---|
| mode | string | |
| origins* | array | [[lat, lon], ...] |
| destinations* | array | [[lat, lon], ...] |
{
"type": "object",
"title": "travel_time_matrixArguments",
"required": [
"origins",
"destinations"
],
"properties": {
"mode": {
"enum": [
"walk",
"bike",
"drive"
],
"type": "string",
"title": "Mode",
"default": "walk"
},
"origins": {
"type": "array",
"items": {
"type": "array",
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
}
]
},
"title": "Origins",
"maxItems": 5,
"minItems": 1,
"description": "[[lat, lon], ...]"
},
"destinations": {
"type": "array",
"items": {
"type": "array",
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
}
]
},
"title": "Destinations",
"maxItems": 5,
"minItems": 1,
"description": "[[lat, lon], ...]"
}
}
}