← Back to EO docs

EO — Tool Reference

Earth observation via Sentinel Hub: satellite scene search, rendered imagery (true color, NDVI, NDWI), and AOI statistics from Sentinel-2. Works with a free Copernicus Data Space account

3 tools · auto-generated from the deployed toolkit

Your AI assistant discovers and invokes these tools through the MCP Server's meta tools — it calls execute_tool with the tool name and arguments below.

# get_statistics read

Compute NDVI/NDWI time-series statistics (mean, min, max) over an AOI without downloading imagery.

Full description
Compute a spectral-index time series over an AOI (Statistical API).

Returns per-interval mean/min/max/std-dev of NDVI or NDWI, as JSON —
ideal for questions like "when was this field greenest last year" or
"how did the reservoir's water extent evolve". Daily intervals return
one entry per satellite pass (gaps are normal); monthly intervals are
cheaper and smoother. Intervals start at time_from and step by the
interval length; a trailing partial interval is included, shortened to
end at time_to (so March 1 - June 30 monthly yields four intervals, the
last covering June 1-30). Works with Sentinel-2 (10 m, data from
2015-06), and with a Planet account also landsat-ot-l2 (30 m) and
byoc-<id> PlanetScope collections (~3 m).
Parameter Type Required Description
aoi object | null No GeoJSON Polygon/MultiPolygon geometry (WGS84). Accepts the geo toolkit's `geojson` output. Provide either aoi or bbox.
bbox array<number> | null No [west, south, east, north] WGS84 degrees. Alternative to aoi.
index "ndvi" | "ndwi" Yes Spectral index: ndvi (vegetation greenness, -1..1) or ndwi (water presence, -1..1).
collection string No Collection id: sentinel-2-l2a (default) or sentinel-2-l1c; with a Planet account also landsat-ot-l2, or byoc-<id> for a PlanetScope subscription collection. Default: "sentinel-2-l2a"
time_from string Yes Start date (YYYY-MM-DD) or ISO datetime.
time_to string Yes End date (YYYY-MM-DD) or ISO datetime.
interval "P1D" | "P1M" No Aggregation interval: P1D (daily) or P1M (monthly, default). Default: "P1M"
max_cloud_cover number | null No Skip scenes above this cloud cover percent when aggregating.
Parameter schema (JSON)
{
  "description": "Parameters for get_statistics.",
  "properties": {
    "aoi": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "GeoJSON Polygon/MultiPolygon geometry (WGS84). Accepts the geo toolkit's `geojson` output. Provide either aoi or bbox.",
      "title": "Aoi"
    },
    "bbox": {
      "anyOf": [
        {
          "items": {
            "type": "number"
          },
          "maxItems": 4,
          "minItems": 4,
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "[west, south, east, north] WGS84 degrees. Alternative to aoi.",
      "title": "Bbox"
    },
    "index": {
      "description": "Spectral index: ndvi (vegetation greenness, -1..1) or ndwi (water presence, -1..1).",
      "enum": [
        "ndvi",
        "ndwi"
      ],
      "title": "Index",
      "type": "string"
    },
    "collection": {
      "default": "sentinel-2-l2a",
      "description": "Collection id: sentinel-2-l2a (default) or sentinel-2-l1c; with a Planet account also landsat-ot-l2, or byoc-<id> for a PlanetScope subscription collection.",
      "title": "Collection",
      "type": "string"
    },
    "time_from": {
      "description": "Start date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time From",
      "type": "string"
    },
    "time_to": {
      "description": "End date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time To",
      "type": "string"
    },
    "interval": {
      "default": "P1M",
      "description": "Aggregation interval: P1D (daily) or P1M (monthly, default).",
      "enum": [
        "P1D",
        "P1M"
      ],
      "title": "Interval",
      "type": "string"
    },
    "max_cloud_cover": {
      "anyOf": [
        {
          "maximum": 100,
          "minimum": 0,
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Skip scenes above this cloud cover percent when aggregating.",
      "title": "Max Cloud Cover"
    }
  },
  "required": [
    "index",
    "time_from",
    "time_to"
  ],
  "title": "GetStatisticsParams",
  "type": "object",
  "additionalProperties": false
}
Result schema (JSON)
{
  "$defs": {
    "IntervalStats": {
      "description": "Index statistics for one time interval.",
      "properties": {
        "interval_from": {
          "description": "Interval start (UTC).",
          "title": "Interval From",
          "type": "string"
        },
        "interval_to": {
          "description": "Interval end (UTC).",
          "title": "Interval To",
          "type": "string"
        },
        "mean": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Mean index value over the AOI.",
          "title": "Mean"
        },
        "min": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Minimum index value.",
          "title": "Min"
        },
        "max": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Maximum index value.",
          "title": "Max"
        },
        "st_dev": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Standard deviation.",
          "title": "St Dev"
        },
        "sample_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Pixels sampled.",
          "title": "Sample Count"
        },
        "no_data_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Pixels with no data.",
          "title": "No Data Count"
        }
      },
      "required": [
        "interval_from",
        "interval_to"
      ],
      "title": "IntervalStats",
      "type": "object"
    }
  },
  "description": "Result of get_statistics.",
  "properties": {
    "success": {
      "description": "Whether the operation succeeded",
      "title": "Success",
      "type": "boolean"
    },
    "index": {
      "description": "Spectral index computed.",
      "title": "Index",
      "type": "string"
    },
    "collection": {
      "description": "Collection used.",
      "title": "Collection",
      "type": "string"
    },
    "interval": {
      "description": "Aggregation interval used.",
      "title": "Interval",
      "type": "string"
    },
    "intervals": {
      "description": "Per-interval statistics, chronological.",
      "items": {
        "$ref": "#/$defs/IntervalStats"
      },
      "title": "Intervals",
      "type": "array"
    },
    "empty_intervals_skipped": {
      "default": 0,
      "description": "Intervals with no usable data (fully cloudy/masked), omitted.",
      "title": "Empty Intervals Skipped",
      "type": "integer"
    },
    "processing_units_spent": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Processing units this call consumed, when reported.",
      "title": "Processing Units Spent"
    },
    "note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Extra guidance, when relevant.",
      "title": "Note"
    }
  },
  "required": [
    "success",
    "index",
    "collection",
    "interval"
  ],
  "title": "GetStatisticsResult",
  "type": "object"
}

# render_image write

Render a satellite image (true color, false color, NDVI, or NDWI) of an AOI and return a displayable URL.

Full description
Render satellite imagery of an AOI to a PNG and return a presigned URL.

Mosaics scenes from the time window (filtered by cloud cover where the
collection supports it, prioritized by mosaicking_order), renders the
chosen visualization, and uploads the PNG to temporary storage. Embed
the returned image_url in a markdown image tag to show it. Default is
Sentinel-2 at 10 m pixels: choose field-scale or larger AOIs (parks,
farms, lakes), not building-scale. With a Planet account, landsat-ot-l2
(30 m) and byoc-<id> PlanetScope collections (~3 m, resolves buildings)
are also renderable. Use search_catalog first to pick a window
containing a clear scene.
Parameter Type Required Description
aoi object | null No GeoJSON Polygon/MultiPolygon geometry (WGS84). Accepts the geo toolkit's `geojson` output; pixels outside it render transparent. Provide either aoi or bbox.
bbox array<number> | null No [west, south, east, north] WGS84 degrees. Alternative to aoi.
visualization "true_color" | "false_color" | "ndvi" | "ndwi" No Rendering: true_color (natural), false_color (vegetation in red), ndvi (greenness ramp), ndwi (water ramp). Default: "true_color"
collection string No Collection id: sentinel-2-l2a (default, 10 m) or sentinel-2-l1c; with a Planet account also landsat-ot-l2 (30 m), or byoc-<id> for a PlanetScope subscription collection (~3 m, sharpest). Default: "sentinel-2-l2a"
time_from string Yes Start date (YYYY-MM-DD) or ISO datetime.
time_to string Yes End date (YYYY-MM-DD) or ISO datetime.
max_cloud_cover number No Only mosaic scenes at or below this cloud cover percent. Prefer 10-30; a value of 0 requires perfectly cloud-free scenes and usually produces an empty image. Default: 30
mosaicking_order "mostRecent" | "leastCC" | "leastRecent" No Scene priority when several match: leastCC (least cloudy, default), mostRecent, or leastRecent. Default: "leastCC"
width integer No Output width in pixels (64-1536); height follows the AOI aspect ratio. Width beyond the AOI's native pixel count at the collection's resolution (10 m Sentinel-2, 30 m Landsat, ~3 m PlanetScope) adds no detail; the server caps excessive values. Default: 512
Parameter schema (JSON)
{
  "description": "Parameters for render_image.",
  "properties": {
    "aoi": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "GeoJSON Polygon/MultiPolygon geometry (WGS84). Accepts the geo toolkit's `geojson` output; pixels outside it render transparent. Provide either aoi or bbox.",
      "title": "Aoi"
    },
    "bbox": {
      "anyOf": [
        {
          "items": {
            "type": "number"
          },
          "maxItems": 4,
          "minItems": 4,
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "[west, south, east, north] WGS84 degrees. Alternative to aoi.",
      "title": "Bbox"
    },
    "visualization": {
      "default": "true_color",
      "description": "Rendering: true_color (natural), false_color (vegetation in red), ndvi (greenness ramp), ndwi (water ramp).",
      "enum": [
        "true_color",
        "false_color",
        "ndvi",
        "ndwi"
      ],
      "title": "Visualization",
      "type": "string"
    },
    "collection": {
      "default": "sentinel-2-l2a",
      "description": "Collection id: sentinel-2-l2a (default, 10 m) or sentinel-2-l1c; with a Planet account also landsat-ot-l2 (30 m), or byoc-<id> for a PlanetScope subscription collection (~3 m, sharpest).",
      "title": "Collection",
      "type": "string"
    },
    "time_from": {
      "description": "Start date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time From",
      "type": "string"
    },
    "time_to": {
      "description": "End date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time To",
      "type": "string"
    },
    "max_cloud_cover": {
      "default": 30,
      "description": "Only mosaic scenes at or below this cloud cover percent. Prefer 10-30; a value of 0 requires perfectly cloud-free scenes and usually produces an empty image.",
      "maximum": 100,
      "minimum": 0,
      "title": "Max Cloud Cover",
      "type": "number"
    },
    "mosaicking_order": {
      "default": "leastCC",
      "description": "Scene priority when several match: leastCC (least cloudy, default), mostRecent, or leastRecent.",
      "enum": [
        "mostRecent",
        "leastCC",
        "leastRecent"
      ],
      "title": "Mosaicking Order",
      "type": "string"
    },
    "width": {
      "default": 512,
      "description": "Output width in pixels (64-1536); height follows the AOI aspect ratio. Width beyond the AOI's native pixel count at the collection's resolution (10 m Sentinel-2, 30 m Landsat, ~3 m PlanetScope) adds no detail; the server caps excessive values.",
      "maximum": 1536,
      "minimum": 64,
      "title": "Width",
      "type": "integer"
    }
  },
  "required": [
    "time_from",
    "time_to"
  ],
  "title": "RenderImageParams",
  "type": "object",
  "additionalProperties": false
}
Result schema (JSON)
{
  "description": "Result of render_image.",
  "properties": {
    "success": {
      "description": "Whether the operation succeeded",
      "title": "Success",
      "type": "boolean"
    },
    "image_url": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Short PNG URL — embed as a markdown image or share as a link. Valid for about a day, then the image is deleted.",
      "title": "Image Url"
    },
    "expires_at": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "ISO-8601 UTC time after which the image is deleted.",
      "title": "Expires At"
    },
    "width": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Rendered width in pixels.",
      "title": "Width"
    },
    "height": {
      "anyOf": [
        {
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Rendered height in pixels.",
      "title": "Height"
    },
    "visualization": {
      "description": "Visualization that was rendered.",
      "title": "Visualization",
      "type": "string"
    },
    "collection": {
      "description": "Collection used.",
      "title": "Collection",
      "type": "string"
    },
    "time_from": {
      "description": "Start of the mosaicking window.",
      "title": "Time From",
      "type": "string"
    },
    "time_to": {
      "description": "End of the mosaicking window.",
      "title": "Time To",
      "type": "string"
    },
    "processing_units_spent": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Processing units this call consumed, when reported.",
      "title": "Processing Units Spent"
    },
    "note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Extra guidance, when relevant.",
      "title": "Note"
    }
  },
  "required": [
    "success",
    "visualization",
    "collection",
    "time_from",
    "time_to"
  ],
  "title": "RenderImageResult",
  "type": "object"
}

# search_catalog read

Search the Sentinel Hub catalog for satellite scenes over an area: acquisition times, cloud cover, and footprints.

Full description
Search satellite scenes (STAC catalog) over an AOI or bbox.

Returns scene ids, acquisition times, cloud cover, and footprints for the
requested collection and time range. Use it to find good (e.g. least
cloudy) dates before calling render_image, or to check data availability
before get_statistics. Free CDSE accounts cover the Sentinel missions;
Landsat/MODIS/commercial collections need Planet credentials with the
endpoint field set to 'planet'.
Parameter Type Required Description
aoi object | null No GeoJSON Polygon/MultiPolygon geometry (WGS84 lon/lat) to search over. Accepts the `geojson`/`merged_geojson` output of the geo toolkit. Provide either aoi or bbox, not both.
bbox array<number> | null No [west, south, east, north] in WGS84 degrees. Alternative to aoi.
collection string No Data collection id, e.g. sentinel-2-l2a (default), sentinel-2-l1c, sentinel-1-grd. Planet-endpoint accounts can also use e.g. landsat-ot-l2, or byoc-<id> for a PlanetScope subscription collection. Default: "sentinel-2-l2a"
time_from string Yes Start date (YYYY-MM-DD) or ISO datetime.
time_to string Yes End date (YYYY-MM-DD) or ISO datetime.
max_cloud_cover number | null No Maximum scene cloud cover percent (optical collections only).
limit integer No Maximum number of scenes to return (1-50). Default: 10
Parameter schema (JSON)
{
  "description": "Parameters for search_catalog.",
  "properties": {
    "aoi": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "GeoJSON Polygon/MultiPolygon geometry (WGS84 lon/lat) to search over. Accepts the `geojson`/`merged_geojson` output of the geo toolkit. Provide either aoi or bbox, not both.",
      "title": "Aoi"
    },
    "bbox": {
      "anyOf": [
        {
          "items": {
            "type": "number"
          },
          "maxItems": 4,
          "minItems": 4,
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "[west, south, east, north] in WGS84 degrees. Alternative to aoi.",
      "title": "Bbox"
    },
    "collection": {
      "default": "sentinel-2-l2a",
      "description": "Data collection id, e.g. sentinel-2-l2a (default), sentinel-2-l1c, sentinel-1-grd. Planet-endpoint accounts can also use e.g. landsat-ot-l2, or byoc-<id> for a PlanetScope subscription collection.",
      "title": "Collection",
      "type": "string"
    },
    "time_from": {
      "description": "Start date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time From",
      "type": "string"
    },
    "time_to": {
      "description": "End date (YYYY-MM-DD) or ISO datetime.",
      "title": "Time To",
      "type": "string"
    },
    "max_cloud_cover": {
      "anyOf": [
        {
          "maximum": 100,
          "minimum": 0,
          "type": "number"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Maximum scene cloud cover percent (optical collections only).",
      "title": "Max Cloud Cover"
    },
    "limit": {
      "default": 10,
      "description": "Maximum number of scenes to return (1-50).",
      "maximum": 50,
      "minimum": 1,
      "title": "Limit",
      "type": "integer"
    }
  },
  "required": [
    "time_from",
    "time_to"
  ],
  "title": "SearchCatalogParams",
  "type": "object",
  "additionalProperties": false
}
Result schema (JSON)
{
  "$defs": {
    "SceneInfo": {
      "description": "One catalog scene.",
      "properties": {
        "id": {
          "description": "Scene/item id (usable for traceability).",
          "title": "Id",
          "type": "string"
        },
        "datetime": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Acquisition time (UTC).",
          "title": "Datetime"
        },
        "cloud_cover": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Scene cloud cover percent, when the collection reports it.",
          "title": "Cloud Cover"
        },
        "bbox": {
          "anyOf": [
            {
              "items": {
                "type": "number"
              },
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Scene footprint bbox [west, south, east, north].",
          "title": "Bbox"
        },
        "thumbnail_url": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Low-res quicklook URL, when the collection provides one.",
          "title": "Thumbnail Url"
        }
      },
      "required": [
        "id"
      ],
      "title": "SceneInfo",
      "type": "object"
    }
  },
  "description": "Result of search_catalog.",
  "properties": {
    "success": {
      "description": "Whether the operation succeeded",
      "title": "Success",
      "type": "boolean"
    },
    "collection": {
      "description": "Collection that was searched.",
      "title": "Collection",
      "type": "string"
    },
    "scene_count": {
      "description": "Number of scenes returned.",
      "title": "Scene Count",
      "type": "integer"
    },
    "scenes": {
      "description": "Matching scenes.",
      "items": {
        "$ref": "#/$defs/SceneInfo"
      },
      "title": "Scenes",
      "type": "array"
    },
    "truncated": {
      "default": false,
      "description": "True when more scenes matched than `limit` returned.",
      "title": "Truncated",
      "type": "boolean"
    },
    "note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Extra guidance, when relevant.",
      "title": "Note"
    }
  },
  "required": [
    "success",
    "collection",
    "scene_count"
  ],
  "title": "SearchCatalogResult",
  "type": "object"
}