Skip to main content
Glama

open-earth-mcp

open-earth-mcp is a Model Context Protocol server that gives an AI assistant (Claude Desktop, Claude Code, or any MCP client) read-only access to open Earth-observation data: Sentinel-2 imagery, ESA WorldCover land cover and the Copernicus 30 m DEM, all from Microsoft Planetary Computer with no API keys. Every answer returns the STAC item IDs and dates it used, its units, a set of sanity checks and plain-language caveats, and a verify tool recomputes key values through a second code path. The assistant can show where each number came from and say when the data is uncertain, so it does not have to guess.

open-earth-mcp: NDVI time series from the demo run and the tool list

flowchart LR
    A["AI assistant<br/>(Claude Desktop, Claude Code,<br/>any MCP client)"] <-- "MCP over stdio<br/>tools / resource / prompt" --> B["open-earth-mcp<br/>validation, cloud masking,<br/>index math, checks"]
    B <-- "STAC search<br/>(signed, read-only)" --> C["Microsoft Planetary Computer<br/>STAC API"]
    B <-- "windowed COG reads" --> D["Cloud-Optimized GeoTIFFs<br/>Sentinel-2 L2A, WorldCover, GLO-30"]

Tools

Tool

What it returns

Data

search_imagery(start, end, bbox | lon+lat, collection, max_cloud, limit)

Scenes covering a place and date range, newest first: ID, time, cloud cover, tile

Sentinel-2 L2A or Landsat C2 L2

ndvi_timeseries(lon, lat, start, end, buffer_m=30)

NDVI for each usable date: mean, std, clear-pixel count, clear fraction, low_confidence and suspect_dip flags; fully cloudy dates are listed under skipped

Sentinel-2 L2A B04/B08 + SCL mask

land_cover(lon, lat, buffer_m=0)

WorldCover class at the point; with a buffer, the share of each class

ESA WorldCover 2021 v200 (10 m)

elevation(lon, lat)

Elevation (m, EGM2008), slope (Horn 3x3), local relief

Copernicus DEM GLO-30

area_summary(bbox, days_back=90)

Small-box report (max 25 km²): land-cover shares, elevation and slope stats, NDVI of the latest scene that is at least 60% clear

all three

verify(lon, lat, days_back=120)

Independent checks with status pass / warn / fail: recomputes NDVI from raw bands, compares native and regridded elevation and land cover, and compares land cover with NDVI

all three

The server also offers:

  • Resource catalog://collections: the supported collections, their resolution, license and required attribution.

  • Prompt describe_place(lon, lat): a template that calls the tools in order, runs verify and asks for an answer with sources and caveats.

Related MCP server: groundstation

Install

git clone https://github.com/landon2199/open-earth-mcp.git
cd open-earth-mcp
conda env create -f environment.yml      # GDAL/rasterio come from conda-forge
conda activate open-earth-mcp
pytest                                   # offline unit tests
pytest -m network                        # one live test against Planetary Computer
python examples/demo_client.py           # full stdio demo, writes examples/demo_output.md

If you already have a geospatial environment, use pip install -e . instead. Python 3.11 or later and the MCP Python SDK 2.x are required. The server is built on mcp.server.mcpserver.MCPServer.

Register with an MCP client

Claude Code

claude mcp add open-earth -- /path/to/envs/open-earth-mcp/bin/python -m open_earth_mcp.server
# or, with the env on PATH:
claude mcp add open-earth -- open-earth-mcp

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "open-earth": {
      "command": "C:\\Users\\<you>\\miniforge3\\envs\\open-earth-mcp\\python.exe",
      "args": ["-m", "open_earth_mcp.server"]
    }
  }
}

Use the full path to the environment's interpreter, because MCP clients start the server without activating conda. On Windows the package puts the environment's own DLL folder first on PATH when it starts, so numpy and GDAL do not load incompatible system DLLs.

Example: question, tool call, answer

All values below come from the run recorded in examples/demo_output.md (22 Oct 2026).

Q: "When did the crop field in the Brazos River bottoms west of Bryan (lon -96.5733, lat 30.6805) green up this year, and how sure are you?"

  1. land_cover(-96.5733, 30.6805, buffer_m=200) → Cropland: 100% of 1,257 WorldCover pixels within 200 m.

  2. ndvi_timeseries(-96.5733, 30.6805, "2025-10-01", "2026-10-22", buffer_m=30) → 53 clear dates (12 cloudy dates skipped). NDVI rose from 0.18 (13 Mar) to 0.45 (10 Apr, 62% of pixels clear) and 0.89 (15 May), and peaked at 0.91 on 1 Jun 2026 (scene S2A_MSIL2A_20260601T170711_R069_T14RQV_…, 29 of 29 pixels clear). By 19 Jul it had fallen to 0.29, which looks like harvest. The 0.36 value on 25 May is flagged suspect_dip: it sits between 0.89 and 0.91 and only 69% of the pixels were clear, so it is more likely missed haze than a real change.

  3. verify(-96.5733, 30.6805) → status pass, 6/6 checks. NDVI for 17 Oct 2026 from the pipeline was 0.1685; reading the raw B04/B08/SCL bands on the scene's own grid gave 0.1683 (|Δ| = 0.0002). Native elevation was 76.16 m and the regridded value 76.12 m.

A (as the assistant should phrase it): "The field greened up between early April and mid-May; there is no clear scene between 10 April and 15 May, so the exact timing is uncertain. NDVI went from 0.18 on 13 March to 0.45 on 10 April and 0.89 by 15 May and peaked at 0.91 on 1 June 2026 (Sentinel-2 scene S2A…20260601, fully clear), then dropped to 0.29 by 19 July, which fits a harvest. One low reading on 25 May is probably haze, not crop change. An independent recompute agreed within 0.001 NDVI."

More numbers from the same run:

Call

Result

elevation(-96.3365, 30.6187) (Texas A&M campus)

107.8 m (EGM2008), slope 2.77°, relief 8.7 m in a 150 m window; native vs regridded 107.8 / 107.4 m

land_cover(-96.3365, 30.6187, 200)

Built-up at the point; within 200 m: 68.1% built-up, 25.1% grassland

area_summary([-96.36, 30.60, -96.32, 30.63])

12.8 km²: 60.2% built-up, 19.5% grassland, 18.6% tree cover; elevation 87.6–131.0 m (mean 102.2); NDVI 0.35 (median 0.33) on 19 Oct 2026, 64.7% of the box clear

verify(-96.3365, 30.6187) (campus)

pass 5/5; NDVI 0.3486 from the pipeline vs 0.3342 from the independent read (

area_summary with a 1.5° × 1° box

Refused: "bbox covers about 15980.0 km^2; the limit is 25 km^2 …"

ndvi_timeseries with lon and lat swapped

Refused: "lat=-96.3365 is outside [-90, 90]. Did you swap lon and lat?"

Design notes

Traceability. Every response includes sources: the STAC API, the collection, the exact item IDs and the acquisition dates. Units appear in key names (elevation_m, buffer_m) or in a units block. The server's MCP instructions tell the assistant to cite them.

Verification. Checks run at two levels.

  • Inline checks in every tool, for example: NDVI within [-1, 1], clear-pixel count > 0, class shares summing to 100%, every scene's processing baseline known, scaled B04/B08 reflectance inside a plausible range ([-0.02, 1.2]; a wrongly applied -1000 offset drives dark pixels below it), and native vs regridded values within tolerance.

  • verify re-derives values through a second, simpler path that reads the native pixels directly with rasterio (no odc-stac and no reprojection) and compares them with the main pipeline. It also checks land cover against NDVI: a vegetated class should have NDVI above 0.1, and water should be below 0.2. A mismatch returns warn and an explanation (for example change since 2021 or a class edge); the server does not choose one answer for you.

Stating uncertainty instead of guessing. Cloudy dates are skipped and listed, not filled in. Partly cloudy dates are flagged low_confidence, and one-date dips that recover on the next date are flagged suspect_dip. The notes say what each dataset can't tell you: WorldCover shows 2021 and has about 77% overall accuracy, and GLO-30 is a surface model that measures roof and canopy heights.

Sentinel-2 details that are easy to get wrong. Since processing baseline 04.00 (January 2022), L2A digital numbers carry a +1000 offset. The server reads s2:processing_baseline for each scene and subtracts the offset before computing NDVI. Without this step NDVI is biased low (see tests/test_offline.py::test_offset_changes_ndvi). Where two MGRS tiles overlap the point, the same-day scenes are loaded separately, each is scaled to reflectance with its own offset, and only then are they mosaicked. A day that mixes baselines (possible around the January 2022 switch) is therefore still correct, is named in the notes, and is covered by a synthetic test (test_mosaic_mixed_baselines_scales_each_scene). Across the switch at the campus point, NDVI stays continuous: 0.27 on 21 Jan 2022 (baseline 03.00) and 0.26 on 26 Jan 2022 (04.00). Clouds are masked with the Scene Classification Layer, keeping only vegetation, not-vegetated and water. Snow/ice pixels are excluded from NDVI and counted per date as snow_pixels; land cover and elevation do not use SCL.

Guardrails.

  • lon/lat ranges are validated, with a hint when lon and lat look swapped.

  • bbox must be at most 25 km², and buffers at most 500 m.

  • Date ranges must be in order, end on or after 23 Jun 2015 (Sentinel-2A launch), span at most 2 years and not start in the future.

  • Collections must be on an allow-list.

  • Each tool call times out after 120 s, and GDAL HTTP has its own timeouts and retries.

  • Every tool is annotated readOnlyHint, and nothing is written.

  • No arbitrary URLs: only the fixed STAC endpoint is queried, and asset links are opened only if they are HTTPS on Planetary Computer storage (*.blob.core.windows.net).

  • Errors come back as short messages the assistant can relay.

Limits. Calls are made to stay fast: point windows of a few pixels, 20 m for box NDVI. A one-year NDVI series takes about 20–55 s and the other tools take 1–12 s. Results depend on the public Planetary Computer service and its signed-URL tokens. NDVI is a top-of-canopy greenness index, not a crop-yield or biomass estimate. Land cover is for 2021.

Project layout

open_earth_mcp/
  server.py       MCP server: tools, resource, prompt, timeouts, error mapping
  data.py         STAC search + COG reads, sources/checks/notes for each tool, verify
  science.py      NDVI, Sentinel-2 offsets, SCL mask, WorldCover classes, Horn slope (pure numpy)
  validation.py   input guardrails (pure Python)
examples/
  demo_client.py  launches the server over stdio with the MCP client SDK and calls every tool
  demo_output.md  transcript of the real run quoted above
  demo_ndvi.json  full NDVI series from that run (used for the hero image)
docs/
  make_hero.py    builds docs/hero.png from demo_ndvi.json
tests/
  test_offline.py unit tests (validation, index math, MCP surface)
  test_network.py live integration test (pytest -m network)

Data licenses and attribution

Data

License / terms

Attribution

Sentinel-2 L2A (Copernicus)

Copernicus Sentinel data legal notice: free, full and open

"Contains modified Copernicus Sentinel data [year]"

ESA WorldCover 2021 v200

CC BY 4.0

"© ESA WorldCover project 2021 / Contains modified Copernicus Sentinel data (2021) processed by ESA WorldCover consortium"

Copernicus DEM GLO-30

Copernicus DEM licence: free use with attribution

"© DLR e.V. 2010-2014 and © Airbus Defence and Space GmbH 2014-2018 provided under COPERNICUS by the European Union and ESA; all rights reserved"

Landsat Collection 2 (search only)

Public domain, USGS

"Landsat imagery courtesy of the U.S. Geological Survey"

Access platform

Microsoft Planetary Computer terms of use

n/a

The same information is available to the assistant at runtime through the catalog://collections resource.

License

Code: MIT © 2026 Landon Melesky. The data keeps its own licenses (see above).

Available Tools

6 tools
area_summaryArea summaryA
Read-onlyIdempotent

Quick report for a small box [west, south, east, north] (max 25 km^2): 2021 land-cover shares, elevation and slope statistics, and NDVI from the most recent Sentinel-2 scene in the last days_back days (15-365) in which at least 60% of the box is clear.

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxYes
days_backNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing the scene-selection rule (most recent Sentinel-2 scene within days_back with ≥60% clear) and the hard 25 km² area cap. It doesn't say what happens when no scene meets the 60% threshold, which is the main residual gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with no wasted clauses: the output content, the area limit, and the scene-selection criteria are all front-loaded and each phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does its job by enumerating the returned metrics and their temporal basis. Minor gaps remain on units (elevation/slope) and the shape of the land-cover shares, but an agent can call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must carry the parameters. It does specify the bbox ordering as [west, south, east, north] and the days_back range 15–365, which is genuinely useful, but it omits the bbox coordinate units (presumably degrees) and doesn't restate the default of 90.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific composite deliverable — land-cover shares, elevation/slope stats, and NDVI — for a bounded box, so the agent knows exactly what it gets back. It doesn't explicitly contrast itself with the sibling tools (land_cover, elevation, ndvi_timeseries), though the word 'Quick report' and the area cap imply the composite route.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 25 km² maximum and the days_back range imply when the tool is appropriate (small areas, recent imagery), but the description never says when to prefer it over the sibling layers or what to do for larger areas. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

elevationElevation and slopeA
Read-onlyIdempotent

Copernicus DEM GLO-30 elevation (metres, EGM2008) at a point, plus slope in degrees (Horn 3x3 on a 30 m grid) and local relief in a 150 m window.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the read-only, idempotent, open-world safety profile, so the description's job is to add semantics — and it does: units (metres, EGM2008 vertical datum), slope derivation method (Horn 3x3 on a 30 m grid), and the 150 m relief window. It doesn't state what happens near coast/nodata cells, but the methodological detail exceeds what the annotations supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the data source and unit, then appends the derived quantities with their algorithms in parentheses. No filler, no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameter descriptions, the description carries the burden of explaining returns, and it does so explicitly (elevation value, slope in degrees, local relief). Only the coordinate convention and edge-case behavior (nodata, ocean) are unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description would ideally clarify coordinate conventions. It implies 'at a point' but never states the expected CRS (presumably WGS84 degrees), nor any bounds; however, lon/lat are self-explanatory names and the omission is low-risk.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific product (Copernicus DEM GLO-30) and precisely enumerates the three returned quantities: point elevation, slope, and local relief. That is far more specific than a restatement of the name, though no sibling (e.g. area_summary, which could plausibly overlap) is named to delimit scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus alternatives, no prerequisites, and none of the siblings (area_summary, land_cover) are referenced. The agent must infer from the description alone that this is the point-query counterpart to area-level tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

land_coverLand cover at a pointA
Read-onlyIdempotent

ESA WorldCover 2021 (10 m) land-cover class at a point, e.g. 40 = Cropland.

With buffer_m > 0 (max 500) also returns the percent share of each class within that radius.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes
buffer_mNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and non-destructive, so the safety profile is covered. The description adds genuinely new context: dataset identity/version, spatial resolution, the class-code encoding, and the max 500 m buffer cap. It does not address no-data/ocean handling, which keeps it at 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, with the core purpose and result encoding front-loaded ahead of the optional-buffer behavior. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does explain returns: a class code at the point, and per-class percent shares when buffer_m > 0. It stops short of describing the shape of the buffered result and leaves coordinate format to inference, so it is strong but not fully self-sufficient for a three-parameter geo tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry all parameter meaning. It explains buffer_m well (values > 0 add per-class percent shares, capped at 500) but says nothing about lat/lon units, ordering, or valid ranges. It compensates for only one of three undocumented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource with provenance and granularity: 'ESA WorldCover 2021 (10 m) land-cover class at a point,' plus a concrete example of the returned encoding (40 = Cropland). That is unmistakably distinct from elevation, ndvi_timeseries, or search_imagery without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by 'at a point' and by the buffer_m clause describing the extra output. There is no explicit statement of when to prefer this over a sibling like area_summary or elevation, and no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ndvi_timeseriesNDVI time seriesA
Read-onlyIdempotent

Sentinel-2 L2A NDVI at a point for every usable scene between start and end (YYYY-MM-DD).

NDVI is averaged over clear 10 m pixels within buffer_m metres (0-500) of the point; clouds, cloud shadow and cirrus are masked with the Scene Classification Layer. Fully cloudy dates are skipped and listed. max_scene_cloud (percent) pre-filters scenes before pixel masking. Each date reports ndvi_mean, ndvi_std, clear_pixels, clear_fraction, item_ids and a low_confidence flag (clear_fraction < 0.5) and a suspect_dip flag (one-date drop > 0.2 that recovers, usually missed haze). Ranges longer than 2 years are refused.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
latYes
lonYes
startYes
buffer_mNo
max_scene_cloudNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/idempotent/openWorld annotations: it describes pixel averaging at 10 m, SCL-based cloud/shadow/cirrus masking, that fully cloudy dates are skipped and listed, that max_scene_cloud is a pre-filter, and the exact thresholds behind the low_confidence and suspect_dip flags. The 2-year refusal limit is also disclosed, so an agent knows the hard failure mode before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what is measured and where, then layers masking behavior, output fields and limits in a compact multi-sentence block with no filler. Given there is no output schema, the enumeration of per-date fields earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly compensates by listing per-date fields (ndvi_mean, ndvi_std, clear_pixels, clear_fraction, item_ids, flags) and by explaining skipped cloudy dates. The overall response envelope (how the per-date list and the skipped-date list are packaged) and NDVI value units/scale are not spelled out, which is the only remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the load, and it does for most parameters: start/end format (YYYY-MM-DD), buffer_m with its 0-500 range, and max_scene_cloud as a scene-level percentage pre-filter. lat/lon are left implied, which is acceptable given they are self-evident, but the missing explicit CRS/units note keeps this from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+scope: Sentinel-2 L2A NDVI at a point for every usable scene in a date range. It is clearly distinct from siblings like search_imagery, land_cover and elevation, since it returns a per-date NDVI series rather than imagery, classes or terrain.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operating context: single point with a buffer, per-scene cadence, and an explicit constraint that ranges longer than 2 years are refused. It does not, however, name alternatives (e.g., when to use search_imagery instead) or state prerequisites like whether the point must be over land.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_imagerySearch satellite imageryA
Read-onlyIdempotent

List satellite scenes covering a place and date range (newest first).

Give either bbox = [west, south, east, north] or a point (lon, lat), in WGS84 degrees. Dates are YYYY-MM-DD (inclusive). collection is "sentinel-2-l2a" or "landsat-c2-l2". max_cloud is the scene-level cloud cover limit in percent; limit caps results (1-50). Returns scene IDs, acquisition times, cloud cover and tile, plus sources/checks/notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
endYes
latNo
lonNo
bboxNo
limitNo
startYes
max_cloudNo
collectionNosentinel-2-l2a

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare read-only, open-world, idempotent, and non-destructive behavior. The description adds useful behavioral context beyond that: results are newest first, and the return includes scene IDs, acquisition times, cloud cover, tile, and sources/checks/notes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it states the main action first, then spatial input, dates, collection, cloud/limit, and return fields. Every sentence adds useful information without repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully states what is returned and in what order. It also covers the key spatial and temporal parameters. Minor omissions such as explicit defaults, required-field restatement, or error behavior are already covered by the schema or are not critical for a read-only search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it does: bbox order and WGS84 units, point lon/lat, YYYY-MM-DD inclusive dates, allowed collection values, max_cloud as scene-level percent, and limit range 1-50. This meaningfully documents all eight parameters even though defaults and required fields remain visible in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: list satellite scenes covering a place and date range. It is clear what the tool does, but it does not explicitly distinguish itself from siblings such as ndvi_timeseries, land_cover, or elevation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the search/list framing and the 'newest first' ordering, but there is no explicit guidance on when to choose this tool over the sibling analysis tools or when not to use it. The description explains invocation shape more than selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verifyVerify values at a pointA
Read-onlyIdempotent

Independent sanity checks at a point. Recomputes NDVI for the latest clear scene (last days_back days) directly from the raw B04/B08/SCL bands on the scene's native grid and compares it with the ndvi_timeseries pipeline; compares native vs regridded elevation and land cover; and checks land cover against NDVI. Returns status pass / warn / fail with each check's detail.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes
days_backNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description correctly spends its words elsewhere: it discloses that computation is done 'directly from the raw bands on the scene's native grid' and that it returns pass/warn/fail with per-check detail. It omits cost/latency expectations for raster reads and what happens when no clear scene exists in the window.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three front-loaded sentences with no filler; the purpose and the three checks are stated before the return contract. Dense but every clause carries information, though the middle sentence packs multiple checks into one long clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, but the description supplies the return contract (pass/warn/fail plus per-check detail) and names all three checks. Remaining gaps — coordinate conventions, behavior when no clear scene is found, and cost — keep it short of complete for a comparison tool that touches multiple raster products.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It does explain `days_back` well ('latest clear scene (last days_back days)') and implies lat/lon via 'at a point', but says nothing about coordinate order, CRS, or the default of 120 days — so compensation is only partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'independent sanity checks at a point' — and enumerates exactly what is checked: NDVI recomputed from raw B04/B08/SCL bands vs. the ndvi_timeseries pipeline, native vs. regridded elevation and land cover, and land cover vs. NDVI. This clearly distinguishes it from the sibling generation tools (ndvi_timeseries, land_cover, elevation) by framing it as a cross-validation step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the phrase 'independent sanity checks' and the explicit comparison with the ndvi_timeseries pipeline suggest it should be used after those products exist, but there is no explicit when-to-use/when-not statement or named alternative. An agent must infer the trigger condition.

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.

  1. 6 tool updatesv0.1.0
    • First observedarea_summary
    • First observedelevation
    • First observedland_cover
    • First observedndvi_timeseries
    • First observedsearch_imagery
    • First observedverify

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation4/5

Each tool has a distinct purpose: scene search, NDVI time series, land cover, elevation, area report, and verification. The only mild overlap is area_summary, which composites land_cover/elevation/NDVI outputs, but its description clearly frames it as a small-box quick report, distinguishing it from the point-based tools.

Naming Consistency3/5

All names are snake_case, but conventions are mixed: some are verb_noun (search_imagery, verify) and others are bare nouns (land_cover, elevation, ndvi_timeseries, area_summary). Readable but not a predictable pattern.

Tool Count5/5

Six tools is well-scoped for an Earth-observation analysis server; each tool covers a distinct analysis primitive with no filler.

Completeness4/5

Core workflows—scene discovery, NDVI, land cover, elevation, summary, and verification—are covered. However, search_imagery returns scene IDs without any tool to fetch actual assets/pixels or download URLs, which is a notable gap for an imagery server, though analysis workflows are not blocked.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to access free, open agronomic data for field briefings, spray windows, water balance, pest pressure, and more, using only public data sources without API keys.
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to autonomously discover, stream, and compute satellite analytics from free government Earth-observation catalogs such as Sentinel-2, Landsat, and Copernicus DEM, with zero API keys or configuration. It supports place-name geocoding, STAC scene search, cloud-native COG streaming for spectral indices, elevation profiles, SAR flood detection, and sandboxed custom geospatial scripts.
    29
    14
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to autonomously discover, stream, and compute satellite analytics from free government Earth observation archives. Provides tools for STAC search, spectral indices, elevation profiles, SAR water detection, and sandboxed geospatial scripting.
    29
    Apache 2.0