EO-MCP

EO-MCP

A Python MCP server for discovering and analyzing Sentinel-2 L2A imagery, enabling AI agents to search scenes, check quality, and compute spectral indices like NDVI, NDWI, and NBR from remote COG windows.

Category
Visit Server

README

EO-MCP

EO-MCP is a Python Model Context Protocol (MCP) server for discovering and analysing Sentinel-2 Level-2A imagery. It gives AI agents a small, focused toolset for finding scenes, checking their suitability, computing spectral indices, and summarising an index inside a polygon.

The server reads only the required windows from cloud-optimized GeoTIFFs hosted by the Microsoft Planetary Computer. It does not download complete Sentinel-2 scenes.

Features

  • Search the live Sentinel-2 L2A STAC catalog by bounding box, date, and cloud cover.
  • Inspect scene-level cloud and nodata metadata before performing analysis.
  • Confirm that a scene footprint covers the requested area of interest.
  • Compute NDVI, NDWI, and NBR from remote raster windows.
  • Calculate polygon-clipped min, max, mean, and pixel count.
  • Return structured, agent-friendly results with processing metadata.

The intended workflow is:

stac_search → scene_quality → compute_index
                          └─→ quick_stats

Always call scene_quality before computing an index.

Tools

Tool Purpose Key inputs
stac_search Find the clearest Sentinel-2 L2A scenes intersecting an area. bbox, start_date, end_date, max_cloud_cover, limit
scene_quality Check cloud cover, nodata, and scene-footprint coverage. scene_id, bbox
compute_index Compute summary statistics for NDVI, NDWI, or NBR over a rectangular area. scene_id, bbox, index_name
quick_stats Compute index statistics clipped to a WGS84 GeoJSON Polygon or MultiPolygon. scene_id, polygon, index_name, all_touched

Bounding boxes use WGS84 coordinates in this order:

[west, south, east, north]

Dates use ISO YYYY-MM-DD format.

Supported indices

Index Formula Typical use
NDVI (B08 - B04) / (B08 + B04) Vegetation condition and greenness
NDWI (B03 - B08) / (B03 + B08) Surface-water detection
NBR (B08 - B12) / (B08 + B12) Burn severity and fire impact

Sentinel-2 digital numbers are converted to reflectance before the index is calculated. EO-MCP also accounts for the offset introduced with processing baseline 04.00 and later.

Requirements

  • Python 3.12 or newer
  • uv
  • Internet access to the Planetary Computer STAC API and Sentinel-2 COG assets

No Planetary Computer API key is required for the current public-data workflow.

Quick start

From the repository root:

uv sync --frozen
uv run python -c "import eo_mcp; print('eo_mcp import: ok')"
uv run fastmcp inspect src/eo_mcp/app.py

The inspect command should report the server name EO-MCP and four tools.

To start the STDIO server manually:

uv run fastmcp run src/eo_mcp/app.py

An STDIO server waits for an MCP client and usually produces no interactive prompt. Use an MCP client or fastmcp call to invoke its tools.

Test from the command line

Search for Sentinel-2 scenes:

uv run fastmcp call \
  --server-spec src/eo_mcp/app.py \
  --target stac_search \
  --input-json '{
    "bbox": [73.0, 33.65, 73.12, 33.75],
    "start_date": "2024-06-01",
    "end_date": "2024-08-31",
    "max_cloud_cover": 10,
    "limit": 1
  }' \
  --json

Check the selected scene:

uv run fastmcp call \
  --server-spec src/eo_mcp/app.py \
  --target scene_quality \
  --input-json '{
    "scene_id": "S2B_MSIL2A_20240603T054639_R048_T43SCT_20240603T090813",
    "bbox": [73.0, 33.65, 73.12, 33.75]
  }' \
  --json

Compute NDVI after the quality check passes:

uv run fastmcp call \
  --server-spec src/eo_mcp/app.py \
  --target compute_index \
  --input-json '{
    "scene_id": "S2B_MSIL2A_20240603T054639_R048_T43SCT_20240603T090813",
    "bbox": [73.0, 33.65, 73.02, 33.67],
    "index_name": "NDVI"
  }' \
  --json

For the installed FastMCP version, pass src/eo_mcp/app.py as the server specification without appending :mcp.

Connect to Codex or another MCP client

EO-MCP currently runs as a local STDIO server. Configure the client with an absolute project path so it can launch the server from any working directory.

{
  "mcpServers": {
    "eo-mcp": {
      "command": "uv",
      "args": [
        "run",
        "--project",
        "/absolute/path/to/eo-mcp",
        "--frozen",
        "fastmcp",
        "run",
        "/absolute/path/to/eo-mcp/src/eo_mcp/app.py"
      ]
    }
  }
}

If the client cannot find uv, replace "uv" with the absolute path returned by:

command -v uv

With the Codex CLI, the equivalent registration command is:

codex mcp add eo-mcp -- \
  /absolute/path/to/uv run \
  --project /absolute/path/to/eo-mcp \
  --frozen fastmcp run \
  /absolute/path/to/eo-mcp/src/eo_mcp/app.py

Restart the client or open a new session after saving the configuration. In Codex, use /mcp to confirm that eo-mcp is connected.

Example agent request:

Find a low-cloud Sentinel-2 scene for Lahore during July 2026. Check the
scene's quality, then compute NDVI for a small area and report the mean.

GeoJSON polygon example

quick_stats accepts either a GeoJSON geometry or a GeoJSON Feature:

{
  "type": "Polygon",
  "coordinates": [
    [
      [73.002, 33.652],
      [73.018, 33.652],
      [73.018, 33.668],
      [73.002, 33.668],
      [73.002, 33.652]
    ]
  ]
}

Coordinates must be WGS84 longitude/latitude values. Polygon and MultiPolygon geometries are supported.

How index processing works

  1. EO-MCP retrieves the requested STAC item and signs its asset URLs.
  2. It transforms the WGS84 area into the source raster coordinate system.
  3. Rasterio reads only the intersecting COG window over HTTPS.
  4. Bands on a different grid are aligned to the reference band.
  5. Digital numbers are converted to reflectance and the selected index is calculated.
  6. The server returns statistics and processing metadata rather than the full raster array.

compute_index reports min, max, mean, median, standard deviation, 2nd and 98th percentiles, pixel counts, CRS, resolution, and the source window. quick_stats clips the index raster to the supplied polygon and reports min, max, mean, and count.

Quality rules and operational limits

A scene is marked usable when all of the following are true:

  • Scene-level cloud cover is at most 20%.
  • Scene-level nodata is at most 10%.
  • The scene footprint covers at least 99% of the requested area.

Important limitations:

  • Cloud and nodata percentages come from scene-level STAC metadata; they are not calculated specifically for the requested bounding box.
  • Index calculations do not apply a per-pixel cloud mask. Select a suitable scene with scene_quality first.
  • A rectangular index request is limited to 4,000,000 reference-grid pixels. Reduce the bounding box if this limit is exceeded.
  • compute_index summarises the full rectangular window. Use quick_stats when results must be clipped to an exact administrative, farm, water, or other polygon boundary.
  • Signed Planetary Computer asset URLs expire. Search again instead of storing them as permanent download links.
  • Large requests depend on remote-network speed and upstream service availability.

Project structure

eo-mcp/
├── pyproject.toml
├── src/
│   └── eo_mcp/
│       ├── __init__.py
│       ├── app.py       # FastMCP server and registered tools
│       ├── tools.py     # STAC, raster, index, and zonal-stat logic
│       └── utils.py     # Input validation helpers
└── README.md

Technology

Remote deployment

STDIO is intended for local clients. To share EO-MCP across machines, expose it using FastMCP's Streamable HTTP transport, add authentication, and deploy it on a Python or container hosting platform. Do not publish an unauthenticated analysis endpoint to the public internet.

See the FastMCP HTTP deployment guide for the supported remote-server patterns.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured