Skip to main content
Glama
README.md
# erddap-mcp

MCP server over the [ERDDAP](https://coastwatch.pfeg.noaa.gov/erddap) ocean-data protocol — the standard keyless data-server protocol behind NOAA CoastWatch satellite SST, Argo profiling floats, IOOS gliders, NDBC buoys, EMODnet physics sensors, NCEI archives and hundreds more.

**Gap:** no existing MCP server for ERDDAP (GitHub search zero hits as of Oct 2026; every "ocean data" MCP found wraps a *single* API — this one speaks the protocol, so it works against **any** ERDDAP server out of the box).

## Tools

| Tool | What it does |
|---|---|
| `list_servers` | Curated public ERDDAP servers (CoastWatch, EMODnet, IFREMER, IOOS gliders, NCEI) |
| `search_datasets` | Keyword search a server's catalogue; returns dataset IDs, titles, institutions |
| `dataset_info` | Title, summary, time/space coverage, and the full queryable variable list |
| `query_tabledap` | Tabular queries: variables + time range + lat/lon box + extra constraints (`!=NaN` etc.), dedup, row cap |
| `query_griddap` | Gridded queries (satellite SST/analysis fields) at a point or box; time defaults to latest grid; stride + cell-count guard |

Works with any ERDDAP base URL: pass a curated nickname or any `https://.../erddap` URL.

## Usage

```bash
pipx install erddap-mcp      # or: pip install erddap-mcp

# stdio (default) — for Claude Code / Cursor / any MCP client
erddap-mcp

# SSE / streamable HTTP for remote clients
erddap-mcp --transport sse --port 8000
erddap-mcp --transport http --port 8000
```

Claude Code config:

```json
{"mcpServers": {"erddap": {"command": "erddap-mcp"}}}
```

No API keys. No configuration. Read-only.

## Development

```bash
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/pytest tests/ -q
```

## Example

```
> search_datasets(server="coastwatch", query="sea surface temperature")
## ERDDAP datasets matching 'sea surface temperature' (15 found)

- jplMURSST41 [Grid]  MUR SST Analysis, ...
- nceiPH53sstd1day [Grid]  NCEI Geo-Potential ...

> query_griddap(server="coastwatch", dataset_id="jplMURSST41", variable="analysed_sst",
                lat_min=36.5, lat_max=37, lon_min=-122.5, lon_max=-122)
## jplMURSST41 / analysed_sst (...)

time | latitude | longitude | analysed_sst (degree_C)
2026-10-22T09:00:00Z | 36.5 | -122.5 | 18.605
...
```

## Notes

- ERDDAP servers are community infrastructure: queries are cached 60 s, row counts capped (default 50, max 500) and griddap cell counts guarded, so the LLM can't accidentally pull a full raster.
- ERDDAP's `Error {code=...; message="..."}` bodies are surfaced as plain readable errors (e.g. wrong variable name → the server's exact complaint).

MIT licensed.