OpenLandMap MCP Server

OpenLandMap MCP Server

Provides access to the OpenLandMap STAC catalog, offering over 100 global environmental datasets including soil, climate, and vegetation data. It enables AI agents to discover, search, and retrieve Cloud-Optimized GeoTIFFs for global geospatial analysis.

Category
Visit Server

README

OpenLandMap MCP Server

MCP Server for the OpenLandMap STAC catalog — full access to global geospatial environmental data for AI agents.

Overview

OpenLandMap provides 104+ collections of global environmental data as Cloud-Optimized GeoTIFFs (COG), covering:

Theme Examples
Soil Organic carbon, pH, texture, bulk density, water content
Vegetation EVI, FAPAR, forest cover, plant functional types
Land Cover Land cover, land use, cropland, pasture, urban areas
Climate Land surface temperature (LST), precipitation, bioclim
Terrain DEM, slope, aspect, curvature, geomorphometry
Water Water occurrence, snow cover
Atmosphere NO2, water vapor, aerosol optical depth
Population Population density, human footprint, wilderness

Installation

cd openlandmap-mcp

# Install with uv
uv pip install -e .

# Or run directly (uv resolves dependencies automatically)
uv run openlandmap-mcp

Configuration

Prerequisites: uv must be installed and available in PATH.

Claude Code

Add to .claude/settings.json (project-level) or ~/.claude/settings.json (global):

{
  "mcpServers": {
    "openlandmap": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/openlandmap-mcp", "openlandmap-mcp"]
    }
  }
}

Claude Desktop

Add to your claude_desktop_config.json:

OS Path
macOS ~/Library/Application Support/Claude/claude_desktop_config.json
Windows %APPDATA%\Claude\claude_desktop_config.json
Linux ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "openlandmap": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/openlandmap-mcp", "openlandmap-mcp"]
    }
  }
}

Gemini CLI

Add to ~/.gemini/settings.json (global) or .gemini/settings.json (project-level):

OS Global path
Linux / macOS ~/.gemini/settings.json
Windows %USERPROFILE%\.gemini\settings.json
{
  "mcpServers": {
    "openlandmap": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/openlandmap-mcp", "openlandmap-mcp"],
      "timeout": 60000
    }
  }
}

After configuration, verify with the /mcp command inside Gemini CLI to list connected servers and available tools.

ChatGPT Desktop

ChatGPT supports MCP servers exclusively via remote HTTP/SSE transport — local stdio processes are not supported. You need to expose the server over HTTP first.

Step 1 — Start the server with SSE transport:

uv run openlandmap-mcp --transport sse --port 8811

Step 2 — Expose locally (for development) or deploy publicly:

For local development, use a tunnel like ngrok:

ngrok http 8811
# Example output: https://abc123.ngrok.app

For production, deploy behind a reverse proxy with a public HTTPS URL.

Step 3 — Register in ChatGPT Desktop:

  1. Open Settings → Apps & Connectors → Advanced Settings
  2. Enable Developer Mode
  3. Go to Settings → Connectors → Create
  4. Fill in:
    • Name: OpenLandMap
    • Connector URL: https://abc123.ngrok.app/mcp (or your public URL)
    • Authentication: None (or configure as needed)

Note: ChatGPT does not support local config files for MCP. All registration is done through the UI. The server must be reachable over HTTPS.

Cursor / VS Code

Add to .cursor/mcp.json (Cursor) or .vscode/mcp.json (VS Code):

{
  "mcpServers": {
    "openlandmap": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/openlandmap-mcp", "openlandmap-mcp"]
    }
  }
}

Compatibility Matrix

Client Transport Config file Local stdio
Claude Code stdio .claude/settings.json Yes
Claude Desktop stdio claude_desktop_config.json Yes
Gemini CLI stdio ~/.gemini/settings.json Yes
ChatGPT Desktop HTTP/SSE UI only (no file) No
Cursor stdio .cursor/mcp.json Yes
VS Code stdio .vscode/mcp.json Yes

Capabilities

1. Catalog Discovery

Browse and search the entire OpenLandMap catalog.

catalog_info()

Returns root catalog metadata: ID, description, STAC version, total collection count.

"What data is available on OpenLandMap?"

list_collections(theme?, keyword?, limit?)

List collections with optional filters by theme alias or keyword search across titles, descriptions, and keywords.

"List all soil collections"
→ list_collections(theme="soil")

"Find collections related to organic carbon"
→ list_collections(keyword="organic carbon")

"Show the first 5 vegetation datasets"
→ list_collections(theme="vegetation", limit=5)

Available theme aliases: soil, vegetation, land_cover, climate, terrain, water, atmosphere, population

get_collection_schema(collection_id)

Returns the full schema of a collection: asset type definitions (MIME types, roles), STAC extensions used, spatial/temporal extent, contact info, style URLs (SLD/QML), and related links.

"Show me everything about the organic carbon collection"
→ get_collection_schema("organic.carbon_usda.6a1c")

discover_data_for_topic(topic)

Natural language search across all collection titles, descriptions, and keywords. Returns results ranked by relevance score.

"Find data about deforestation in the Amazon"
→ discover_data_for_topic("Amazon deforestation forest loss")

"What datasets exist for air quality analysis?"
→ discover_data_for_topic("air quality NO2 aerosol")

2. Collection Operations

Analyze, compare, and explore collections in depth.

compare_collections(collection_ids)

Side-by-side comparison of 2–10 collections: temporal coverage, resolution, units, keywords, and theme.

"Compare soil organic carbon and pH datasets"
→ compare_collections(["organic.carbon_usda.6a1c", "ph.h2o_usda.4c1a2a"])

get_collection_temporal_stats(collection_id)

Temporal statistics: earliest/latest dates, item count, year-by-year distribution, and median update interval.

"How often is the EVI dataset updated?"
→ get_collection_temporal_stats("evi_mod13q1.tmwm.inpaint")

find_related_collections(collection_id)

Finds collections sharing the same theme or native category. Useful for discovering complementary datasets.

"What other datasets are related to land surface temperature?"
→ find_related_collections("lst_mod11a2.daytime")

get_soil_collections()

Shortcut returning all soil-related collections (bulk density, organic carbon, pH, sand/clay/silt, texture, water content, taxonomy).

"List all available soil datasets"
→ get_soil_collections()

get_vegetation_collections()

Shortcut returning all vegetation-related collections (EVI, FAPAR, forest cover, plant functional types).

"What vegetation indices are available?"
→ get_vegetation_collections()

get_land_cover_collections()

Shortcut returning all land cover/land use collections (classification, cropland, pasture, urban, change detection).

"Show me land cover datasets"
→ get_land_cover_collections()

3. Item Search & Access

Search and retrieve individual temporal snapshots within collections.

search_items(collection_id, bbox?, datetime_range?, limit?, offset?)

Search items with spatial (bounding box) and temporal (ISO 8601 interval) filters. Supports pagination.

"Find organic carbon data for the Cerrado region"
→ search_items("organic.carbon_usda.6a1c", bbox=[-60.47, -24.68, -41.28, -2.33])

"Get EVI data from 2015 to 2020"
→ search_items("evi_mod13q1.tmwm.inpaint", datetime_range="2015-01-01/2020-12-31", limit=10)

"Show all items in the land cover collection"
→ search_items("land.cover_esacci.lc.l4", limit=50)

get_item_detail(collection_id, item_id)

Full item details: geometry (GeoJSON), bounding box, temporal range, all assets with resolved URLs, MIME types, file sizes, and checksums.

"Show full details for the 2018 organic carbon item"
→ get_item_detail("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231")

list_items_temporal(collection_id)

Lists all items sorted chronologically. Shows the complete temporal coverage and update pattern of a dataset.

"What time periods are available for EVI?"
→ list_items_temporal("evi_mod13q1.tmwm.inpaint")

find_items_by_point(lon, lat, collection_ids?)

Given a WGS84 coordinate, finds all items covering that point across one or more collections.

"What data is available for Brasília?"
→ find_items_by_point(-47.9, -15.8)

"Find soil data at this location"
→ find_items_by_point(-47.9, -15.8, ["organic.carbon_usda.6a1c", "ph.h2o_usda.4c1a2a"])

4. Asset Access & Download

Resolve URLs and generate download instructions for data files.

get_asset_url(collection_id, item_id, asset_key)

Resolves the full S3 URL for a specific asset. Returns MIME type, roles, COG status, file size, checksum, and S3 bucket/key.

"Get the URL for the 0cm depth organic carbon layer"
→ get_asset_url("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231", "organic.carbon_usda.6a1c_m_250m_b0cm")

list_assets_for_item(collection_id, item_id)

Lists all assets (data layers, thumbnails, style files) with complete metadata for each.

"What files are available in this item?"
→ list_assets_for_item("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231")

get_all_data_assets(collection_id, item_id)

Filters to only data assets (role="data"), excluding thumbnails, QML, and SLD files. Returns direct COG URLs.

"Give me only the data layers, not the styles"
→ get_all_data_assets("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231")

get_asset_download_info(collection_id, item_id, asset_key)

Returns the direct URL plus ready-to-use commands and code snippets:

  • curl command for download
  • wget command for download
  • Python snippet using rasterio (streaming, no download needed)
  • R snippet using terra (streaming, no download needed)
"How do I access the soil carbon data programmatically?"
→ get_asset_download_info("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231", "organic.carbon_usda.6a1c_m_250m_b0cm")

get_visualization_assets(collection_id, item_id)

Returns visualization-related assets: thumbnails (PNG), QGIS layer styles (QML), and WMS style descriptors (SLD).

"Get the QGIS style file for this layer"
→ get_visualization_assets("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231")

5. Spatial Queries

Work with geographic regions and spatial coverage.

get_bbox_for_region(region_name)

Returns the WGS84 bounding box [west, south, east, north] for a named region. Supports ~50 regions:

  • Countries: brazil, usa, china, india, australia, germany, france, japan, mexico, argentina, colombia, south_africa, kenya, indonesia, etc.
  • Brazilian states: goias, mato_grosso, para, minas_gerais, sao_paulo, bahia, amazonas, tocantins, maranhao, rondonia, acre, roraima, amapa, etc.
  • Brazilian biomes: cerrado, amazon, amazonia_legal, caatinga, pantanal, mata_atlantica, pampa
  • Continents/regions: south_america, north_america, europe, africa, asia, southeast_asia, oceania, middle_east, global
"What's the bounding box for the Cerrado biome?"
→ get_bbox_for_region("cerrado")
# Returns: {"region": "cerrado", "bbox": [-60.47, -24.68, -41.28, -2.33]}

"Get the bbox for Goiás state"
→ get_bbox_for_region("goias")

find_collections_for_bbox(bbox, theme?)

Finds all collections whose spatial extent intersects the given bounding box. Optionally filters by theme.

"What soil data covers the Cerrado?"
→ find_collections_for_bbox([-60.47, -24.68, -41.28, -2.33], theme="soil")

"Find all datasets available for Southeast Asia"
→ find_collections_for_bbox([92.0, -11.0, 141.0, 28.0])

get_collection_spatial_coverage(collection_id)

Returns full spatial coverage: bounding box, GeoJSON polygon of the extent, ground sample distance (resolution in meters), and CRS.

"What is the spatial resolution of the elevation model?"
→ get_collection_spatial_coverage("dtm.bareearth_ensemble")

6. Analysis & Code Generation

Discover data by topic, analyze temporal coverage, and generate ready-to-use code.

get_data_timeline(collection_ids)

Generates a structured timeline showing data availability across 1–10 collections. Useful for planning multi-temporal analyses.

"Show me when soil and vegetation data overlap"
→ get_data_timeline(["organic.carbon_usda.6a1c", "evi_mod13q1.tmwm.inpaint"])

find_overlapping_datasets(collection_id, start_year, end_year)

Finds all other collections with temporal overlap in the given period. Useful for multi-variable correlation studies.

"What datasets overlap with land cover data between 2010 and 2020?"
→ find_overlapping_datasets("land.cover_esacci.lc.l4", 2010, 2020)

get_stac_item_as_geojson(collection_id, item_id)

Returns the item as a pure GeoJSON Feature, ready for use in any GIS tool, web map, or geospatial pipeline.

"Export this item as GeoJSON"
→ get_stac_item_as_geojson("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231")

build_python_snippet(collection_id, item_id, asset_key, operation)

Generates a ready-to-run Python code snippet using rasterio and matplotlib.

Operations: open, info, plot, clip_bbox, stats, export_csv

"Generate Python code to plot organic carbon data"
→ build_python_snippet("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231", "organic.carbon_usda.6a1c_m_250m_b0cm", "plot")

"Generate code to compute statistics"
→ build_python_snippet(..., operation="stats")

"Generate code to clip to a bounding box"
→ build_python_snippet(..., operation="clip_bbox")

build_r_snippet(collection_id, item_id, asset_key, operation)

Generates a ready-to-run R code snippet using terra and sf.

Operations: open, info, plot, clip_bbox, stats, export_csv

"Generate R code to open and plot this raster"
→ build_r_snippet("organic.carbon_usda.6a1c", "organic.carbon_usda.6a1c_19500101_20171231", "organic.carbon_usda.6a1c_m_250m_b0cm", "plot")

MCP Resources

Static data accessible via URI patterns:

URI Description
stac://openlandmap/catalog Root catalog metadata (ID, version, collection count)
stac://openlandmap/themes Index of all collections organized by thematic category
stac://openlandmap/guide Usage guide with quick-start instructions
stac://openlandmap/collection/{id} Full metadata for a specific collection
stac://openlandmap/collection/{id}/item/{item_id} Full item details including all assets

MCP Prompts

Pre-built workflow templates for common analysis patterns:

Prompt Description Parameters
explore_collection Step-by-step exploration of a collection (schema, temporal coverage, assets, related data) collection_id
find_data_for_analysis Guided workflow to find data for a specific analysis (region + topic + period) topic, region, period
download_workflow Complete data access workflow with URLs, commands, and code snippets collection_id, item_id

Usage Examples

"What data is available on OpenLandMap?"
"List all soil datasets"
"Find collections about organic carbon"
"Show the temporal coverage of evi_mod13q1.tmwm.inpaint"
"Find vegetation data for the Cerrado between 2015 and 2020"
"Generate a Python snippet to access EVI data"
"Compare soil collections: organic.carbon vs ph.h2o"
"What is the spatial resolution of the elevation dataset?"
"Find datasets that overlap temporally with land cover between 2010-2020"
"Generate R code to plot soil organic carbon"
"What data is available at coordinates -47.9, -15.8?"
"Export this STAC item as GeoJSON for use in QGIS"
"How do I download the bulk density dataset with curl?"
"Show me the QGIS style file for the pH collection"

Architecture

  • Static catalog: Data is served from S3 (Wasabi) as static STAC JSONs — no server-side search API
  • In-memory cache: Configurable TTL per resource type (1h catalog, 30min collections, 10min items)
  • Lazy loading: Collections fetched on demand with concurrent batch fetch (semaphore-limited) when global filtering is needed
  • No native dependencies: Pure Python and pre-built wheels only (no GDAL/GEOS compilation required)
  • Retry with backoff: Automatic retry (3 attempts, exponential delays 1s/2s/4s) for all HTTP requests
  • Thundering herd protection: Per-key async locks prevent duplicate fetches for the same resource

License

OpenLandMap data is distributed under CC-BY-SA-4.0.

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