# mcgibs

NASA satellite imagery for LLMs.

An [MCP](https://modelcontextprotocol.io/) server that connects language models to [NASA GIBS](https://www.earthdata.nasa.gov/engage/open-data-services-software/earthdata-developer-portal/gibs-api) (Global Imagery Browse Services) — 1000+ satellite visualization layers covering the entire Earth, updated daily.

**Three pillars:**

- **Discovery** — search layers by keyword, browse measurement categories, check date availability
- **Imagery** — fetch satellite images by place name and date, compare dates side-by-side, composite multiple layers
- **Interpretation** — natural-language colormap explanations, legend graphics, scientific context

No API key required. All data is freely available from NASA.

## Quick Start

### From PyPI

```bash
uvx mcgibs
```

### Add to Claude Code

```bash
claude mcp add mcgibs -- uvx mcgibs
```

### Local development

```bash
git clone https://git.supported.systems/rpm/mcgibs.git
cd mcgibs
uv sync --all-extras
uv run mcgibs
```

Or add a local dev server to Claude Code:

```bash
claude mcp add mcgibs-local -- uv run --directory /path/to/mcgibs mcgibs
```

## Tools

| Tool | Description |
|------|-------------|
| `search_gibs_layers` | Search 1000+ layers by keyword, measurement, period, or status |
| `get_layer_info` | Full metadata for a layer — instrument, platform, resolution, dates |
| `list_measurements` | All measurement categories with layer counts |
| `check_layer_dates` | Available date range for a layer (capabilities + live DescribeDomains) |
| `get_imagery` | Fetch satellite imagery by layer, date, and place name or bbox |
| `compare_dates` | Side-by-side comparison of two dates for change detection |
| `get_imagery_composite` | Overlay up to 5 layers into a single composite image |
| `explain_layer_colormap` | Natural-language explanation of what colors represent |
| `get_legend` | Pre-rendered legend graphic for a layer |
| `resolve_place` | Geocode a place name to coordinates and bounding box |
| `build_tile_url` | Construct a direct WMTS tile URL for embedding |

## Resources

| URI | Description |
|-----|-------------|
| `gibs://catalog` | Full layer catalog grouped by measurement category |
| `gibs://layer/{layer_id}` | Individual layer metadata as JSON |
| `gibs://colormap/{layer_id}` | Colormap explanation for a layer |
| `gibs://dates/{layer_id}` | Available date range for a layer |
| `gibs://projections` | Supported GIBS projections and endpoints |

## Prompts

| Prompt | Parameters | Description |
|--------|------------|-------------|
| `earth_overview` | *(none)* | Introduction to GIBS with suggested explorations |
| `investigate_event` | `event_type`, `location`, `date` | Guided workflow for investigating natural events |
| `satellite_snapshot` | `place`, `date` | Quick satellite view of any location |
| `climate_monitor` | `indicator`, `location`, `start_date`, `end_date` | Track climate changes over time |
| `layer_deep_dive` | `layer_id`, `location`, `date` | Full scientific analysis of a single layer |
| `multi_layer_story` | `topic`, `location`, `date` | Data journalism — composite layers to tell a story |
| `polar_watch` | `pole`, `date`, `compare_date` | Arctic/Antarctic ice and snow monitoring |

## Example Workflows

### Investigating a wildfire

```
User: Use the investigate_event prompt for the 2025 LA wildfires

→ search_gibs_layers("fire")
→ search_gibs_layers("true color")
→ check_layer_dates("MODIS_Terra_CorrectedReflectance_TrueColor")
→ get_imagery("MODIS_Terra_CorrectedReflectance_TrueColor", "2025-01-08", place="Los Angeles")
→ get_imagery("MODIS_Fires_Terra", "2025-01-08", place="Los Angeles")
→ compare_dates("MODIS_Terra_CorrectedReflectance_TrueColor", "2025-01-01", "2025-01-10", place="Los Angeles")
→ explain_layer_colormap("MODIS_Fires_Terra")
```

### Monitoring sea ice decline

```
User: Use climate_monitor to track Arctic sea ice from March to September

→ search_gibs_layers("sea ice")
→ check_layer_dates("AMSR2_Sea_Ice_Concentration_12km")
→ explain_layer_colormap("AMSR2_Sea_Ice_Concentration_12km")
→ compare_dates("AMSR2_Sea_Ice_Concentration_12km", "2025-03-01", "2025-09-01", bbox=[-180,60,180,90])
→ get_legend("AMSR2_Sea_Ice_Concentration_12km")
```

### Quick look at anywhere on Earth

```
User: Use satellite_snapshot for the Great Barrier Reef

→ resolve_place("Great Barrier Reef")
→ get_imagery("MODIS_Terra_CorrectedReflectance_TrueColor", "2025-06-01", place="Great Barrier Reef")
→ search_gibs_layers("chlorophyll")
→ get_imagery_composite(["MODIS_Terra_CorrectedReflectance_TrueColor", "MODIS_Terra_Chlorophyll_A"], "2025-06-01", place="Great Barrier Reef")
```

## Projections

| EPSG | Description | Use case |
|------|-------------|----------|
| 4326 | Geographic (WGS84) | Default — global coverage, most layers |
| 3857 | Web Mercator | Web map tiles, Leaflet/Mapbox integration |
| 3413 | Arctic Polar Stereographic | Arctic-focused imagery |
| 3031 | Antarctic Polar Stereographic | Antarctic-focused imagery |

## Development

```bash
uv sync --all-extras

# Lint
uv run ruff check src/ tests/

# Tests
uv run pytest

# Build
uv build
```

## Architecture

```
src/mcgibs/
  server.py       MCP server — tools, resources, prompts, middleware
  client.py       GIBS HTTP client — WMS, WMTS, colormaps, geocoding
  capabilities.py WMTS GetCapabilities parser and layer search
  colormaps.py    Colormap XML parser and natural-language interpreter
  models.py       Pydantic models — Layer, BBox, GeoResult, ColormapEntry
  constants.py    API endpoints, projections, tile matrix definitions
  geo.py          Bounding box math and geocoding helpers
```

## License

[MIT](LICENSE)

## Links

- [NASA GIBS](https://www.earthdata.nasa.gov/engage/open-data-services-software/earthdata-developer-portal/gibs-api)
- [GIBS API Documentation](https://nasa-gibs.github.io/gibs-api-docs/)
- [Worldview](https://worldview.earthdata.nasa.gov/) — NASA's browser-based GIBS viewer
- [FastMCP](https://gofastmcp.com/) — the MCP framework powering this server
- [Source](https://git.supported.systems/rpm/mcgibs)
