copernicus-mcp
copernicus-mcp
A self-hosted Model Context Protocol server that gives MCP-compatible LLM agents local, reproducible access to Copernicus environmental data — observations, reanalysis, forecasts, and climate indicators.
Two backends are currently supported, both using Copernicus services that are free to register for: Copernicus Marine, CDS, ADS, and EWDS.
Copernicus Marine (CMEMS) — 1,251 datasets across 306 products in the bundled catalogue snapshot: physics, biogeochemistry, sea ice, ocean colour, SST, sea level, waves, wind, and in-situ observations. Supports discovery, subsetting, native-file retrieval, and sync or async downloads.
Climate Data Store family (CDS / ADS / EWDS) — 164 datasets in the bundled snapshot across reanalysis, satellite, in-situ, atmospheric composition (CAMS), and emergency-management (EFAS / GloFAS / CEMS) data. Uses queue-based asynchronous retrieval with offline discovery from a bundled catalogue snapshot. A request that exceeds a dataset's server-side cost limit is split automatically along the calendar axis and returned as one multi-file workflow under a single request id.
Ask in plain English. The server finds, filters, estimates, and downloads. Large downloads are size-estimated, gated for explicit confirmation, cached, and returned as a filepath + metadata + provenance descriptor rather than inline bytes. Every retrieval lands with an MD5-sealed sidecar JSON so the exact request is reproducible later. Long-running requests run asynchronously — submit one and poll it later, or list and reclaim your past jobs from a fresh session, because the local job store survives restarts.
"Get me Mediterranean Sea salinity forecasts for next week, then fetch the AMOC strength time series for the last 5 years."
Install
No hosted endpoint. No vendor account. No data upload. Python 3.11+ required.
With venv (stdlib, no extra tools)
python -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
pip install "copernicus-mcp[cmems,cds]" # both backends (recommended)
# pip install "copernicus-mcp[cmems]" # CMEMS only
# pip install "copernicus-mcp[cds]" # CDS / ADS / EWDS onlyWith conda / mamba / micromamba
The package is currently published on PyPI only (no conda-forge feedstock yet) — so pip install inside a fresh conda environment is the path:
mamba create -n copernicus python=3.11 pip # or `conda create ...`
mamba activate copernicus
pip install "copernicus-mcp[cmems,cds]"The MCP client config (next section) then points at /path/to/your/conda/envs/copernicus/bin/copernicus-mcp instead of the venv path. Run which copernicus-mcp inside the activated environment to find the exact location.
Credentials
The Copernicus services own the credentials — we never see them.
CMEMS (free account at https://data.marine.copernicus.eu/register):
copernicusmarine login # writes ~/.copernicusmarine/.copernicusmarine-credentialsCDS / ADS / EWDS — a single Personal Access Token works across all three stores under ECMWF's unified-token policy. Get it at https://cds.climate.copernicus.eu/ → user profile:
export CDSAPI_KEY=<your-uuid-pat>
# or write to ~/.cdsapirc (same format the cdsapi CLI uses)Some CDS-family datasets require accepting their licence once; when that happens the server returns the acceptance URL in a structured TermsNotAcceptedError.
Configure your MCP client
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your platform:
{
"mcpServers": {
"copernicus": {
"command": "/absolute/path/to/.venv/bin/copernicus-mcp",
"args": ["serve"]
}
}
}Restart Claude Desktop. Tools become available the next time you open a chat.
Claude Code
claude mcp add copernicus -- /absolute/path/to/.venv/bin/copernicus-mcp serveOther MCP clients
Any client that speaks MCP over stdio works. Point it at the copernicus-mcp serve command in your virtualenv.
Smoke test
After install, confirm the server starts and your credentials resolve:
copernicus-mcp statusThe output lists configured backends and where credentials were resolved from — without ever printing the credential values themselves.
Try these prompts
Drop these into a chat with the server connected. Each one walks through the discovery → estimate → download flow and lands a real file on your disk.
# | Prompt | What the agent does |
1 | "Mediterranean salinity forecast for the next 7 days." | Routes to the |
2 | "How has Arctic sea-ice extent changed over the last 5 years?" | Routes to the |
3 | "Get me the AMOC strength timeseries at 26°N." | Intent-heavy query — routes to |
4 | "ERA5 hourly 2m temperature over Europe for January 2024." | CDS path → describes |
5 | "Global CO₂ atmospheric forecasts for next week." | ADS path → finds |
The discovery routing is covered offline by bench/marine_routing_bench.py; the full submit-download flows are covered by tests/integration/ and require live CMEMS / CDS credentials with RUN_INTEGRATION_TESTS=1.
Tools
Backend | Tool | Purpose |
diagnostic |
| Configured backends, cache size, override hints. No credentials in output. |
| Recover past jobs across sessions: list recent submissions (id, backend, dataset, status) from local state — no | |
CMEMS |
| Hierarchical discovery — narrows ~1251 datasets in two hops via 47 hand-curated routing groups. Offline, no embeddings, no LLM at query time. |
| Full metadata: variables, axes, spatial / temporal extent, services, DOI. | |
| The dataset's actual lon/lat/depth/time axes — summarised for long axes. | |
| Preview the download size before running it — an approximate estimate, not a guarantee. | |
| Download a spatio-temporal subset. Large requests require explicit confirmation. | |
| For sparse / in-situ datasets (CORA, EasyCORA, INSITU-BGC, MULTIOBS): filter by bbox / time / variables, then download the precise file list. | |
| Async lifecycle. | |
CDS / ADS / EWDS |
| Hierarchical group discovery + filters (bbox / time_range / variable / domain / category). |
| Bundled snapshot + live narrowing against the store's constraints endpoint. | |
| Self-calibrating size estimate + costing pre-flight (flags requests the server will reject); honest "unknown" for whole-file products. The byte size is approximate (see note below). | |
| Valid field values for a (partial) request; anonymous. | |
| Async queue lifecycle. T&C-not-accepted surfaces as a structured error with the accept-URL. |
Tools that return large data return {filepath, uri, metadata, provenance} — never inline bytes. The copernicus://files/{cache_key}, copernicus://jobs/{request_id}, and copernicus://provenance/{record_id} resources surface the cached artifacts to MCP clients that prefer the resource API.
Size estimates are approximate. The byte size from
cds_estimate_request/marine_estimate_subset(and the size shown at the confirmation gate) is a heuristic or calibration-based figure and can be wrong by a large factor — treat it as a rough order-of-magnitude, not a guarantee. Don't rely on it for hard limits, quotas, billing, or disk provisioning. The CDS server cost units are exact; only the byte size is uncertain. Every CDS estimate response also carries asize_estimate_caveatfield restating this.
For complete schemas read the inline tool descriptions your MCP client surfaces, or the detailed reference in docs/tools.md.
How it works
┌──────────────────────────┐ ┌─────────────────────────────┐
│ Claude / Claude Code / │ │ copernicus-mcp serve │
│ any MCP client │ stdio │ (local Python process) │
└──────────────────────────┘ ────▶ │ │
│ hierarchical discovery │
│ size estimate + gate │
│ retrieval + provenance │
│ cache + idempotent re-use │
└──────────────┬──────────────┘
│
┌──────────────────────────┼────────────────────────┐
▼ ▼ ▼
Copernicus Marine Climate Data Store local cache
(Mercator Ocean) CDS / ADS / EWDS ~/Library/Caches/...
copernicusmarine SDK cdsapi SDK (per-OS paths)Hierarchical discovery uses bundled JSON manifests (slim records → enriched cards → product summaries → routing groups). Scoring is deterministic phrase matching. The catalogue + groups are committed JSON, so "why did this query return that group" is auditable.
Limitations
The server does not bypass Copernicus licences or access controls — credentials and licence acceptance remain the user's responsibility.
CDS-family downloads depend on upstream queue availability; large requests may take minutes to hours.
Catalogue snapshots are bundled at release time and may lag behind the live Copernicus catalogues. Re-publish a new version when the snapshots are refreshed.
Hierarchical routing is pattern-based; it does not use embeddings or an LLM at query time. Misroutes on highly ambiguous queries are possible.
Configuration
The system runs out of the box. Override via env vars (COPERNICUS_MCP_CACHE_DIR, COPERNICUS_MCP_STATE_DB, COPERNICUS_MCP_LOG_LEVEL, COPERNICUS_MCP_ENABLED_BACKENDS=cmems,cds), a YAML file at ~/.config/copernicus-mcp/config.yaml, or --cache-dir PATH on the entry-point binary.
HPC / networked home directories: the workflow-state SQLite database defaults to the user state directory, which on many clusters is NFS. The server detects a network filesystem and uses a safe journal mode automatically (with a loud, bounded fallback instead of a silent hang), but for per-run isolation you can also point
COPERNICUS_MCP_STATE_DBat a node-local or per-run path. Keep it on a shared path if one process submits and another polls across nodes.
Cache directories are per-OS via platformdirs: Linux ~/.cache/copernicus-mcp/, macOS ~/Library/Caches/copernicus-mcp/, Windows %LOCALAPPDATA%\copernicus-mcp\Cache\.
Download location is fixed at startup. To change where files are written, set
COPERNICUS_MCP_CACHE_DIR(or--cache-dir/config.yaml) before launching the server — there is no per-request override and it cannot be changed while the server is running. Decide this before pointing an MCP client (or agent) at the server; changing it later requires a restart.
Full reference: docs/setup.md.
Status
Latest release: see releases page (current: v0.4.3). Two backends in production: CMEMS + Climate Data Store family. CDSE, Sentinel Hub, WEkEO planned for subsequent iterations.
License
BSD 3-Clause. See LICENSE. Dependencies are EUPL-1.2 (copernicusmarine), Apache-2.0 (cdsapi and most others), MIT or BSD.
Acknowledgements
ECMWF for
cdsapiand for operating the Climate / Atmosphere / Early Warning data stores.The Copernicus programme for the underlying data.
The Anthropic team for the Model Context Protocol specification and Python SDK.
Related projects
AQUAVIEW MCP — hosted MCP server unifying ~700K datasets across 68 NOAA / IOOS / EMODnet / Argo / GOES-R / Sentinel collections. If your question reaches beyond Copernicus into US / global multi-agency oceanographic and atmospheric data, that's the natural complement to this server.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/CliDyn/copernicus-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server