A Model Context Protocol server for the free Open-Meteo APIs. Plug it into Claude Desktop, Claude Code or any MCP client, then ask in plain language:
What were the temperatures in London during January 2023?
Compare the ICON and GFS ensemble forecasts for Berlin over the next 5 days.
Give me the current European AQI, UV index and pollen levels in Paris.
No API key is needed: Open-Meteo is free for non-commercial use.
Features
- 17 tools covering forecasts, ERA5 history, air quality, marine, flood, seasonal, ensemble and CMIP6 climate data, plus geocoding and elevation
- Model-specific forecasts from DWD ICON, NOAA GFS, Météo-France, ECMWF, JMA, MET Norway and Environment Canada GEM
- Built for LLMs: strict input schemas, server instructions that tell the model which tool answers which question, compact JSON responses capped at 25,000 characters
- Two transports: stdio for local clients, stateless Streamable HTTP for remote deployments, with API key auth, rate limiting and origin checks
- In-memory response cache with per-endpoint TTLs, so repeated questions don't hit Open-Meteo again
- Self-hosting friendly: every Open-Meteo endpoint can point at your own instance
Getting started
You need Node.js 22 or later. Nothing to install beforehand: npx fetches the server on first run.
Claude Desktop
Add the server to your claude_desktop_config.json:
{
"mcpServers": {
"open-meteo": {
"command": "npx",
"args": ["-y", "-p", "open-meteo-mcp-server", "open-meteo-mcp-server"]
}
}
}
Claude Code
claude mcp add open-meteo -- npx -y -p open-meteo-mcp-server open-meteo-mcp-server
Other MCP clients
Any client that launches stdio servers works with the same command: npx -y -p open-meteo-mcp-server open-meteo-mcp-server. You can also install it globally with npm install -g open-meteo-mcp-server and run open-meteo-mcp-server.
[!TIP]
Every data tool takes coordinates. Ask with a place name and the model will call geocoding first to resolve it.
weather_forecast is the default choice. The model-specific tools are for when a particular model is asked for, or to compare models with one call each.
Responses
- Times are GMT unless
timezone is set. timezone: "auto" uses the location's local time.
null in a series means the model has no value for that time, not zero.
- Responses over 25,000 characters have their
hourly / daily / minutely_15 arrays shortened by the same ratio, keeping series aligned, and gain truncated: true with a truncation_message. Narrow the date range or the variables to get everything.
The full list of variables and parameters is in each tool's input schema and in the Open-Meteo documentation.
Remote deployment
Set TRANSPORT=http to serve MCP over Streamable HTTP at /mcp instead of stdio:
TRANSPORT=http HOST=0.0.0.0 PORT=3000 API_KEY=your-secret-key npx open-meteo-mcp-server
Clients then send the key with every request, as Authorization: Bearer <key> or X-API-Key: <key>. GET /health answers {"status":"ok"} without a key, for container probes.
The transport is stateless: each POST /mcp is handled on its own, no session ID is issued, and GET / DELETE /mcp answer 405. No tool keeps state between calls, so clients lose nothing.
[!IMPORTANT]
The server binds to 127.0.0.1 by default, so it is reachable only from the local machine. Set HOST=0.0.0.0 to accept remote connections, and set API_KEY whenever you do: without it, the server runs in open mode.
Docker
A prebuilt image is published to the GitHub Container Registry. It already binds to 0.0.0.0:
docker run -d --name open-meteo-mcp -p 3000:3000 \
-e API_KEY=your-secret-key \
ghcr.io/cmer81/open-meteo-mcp:latest
Tags follow the npm version without the v prefix: latest, 2.5.1, 2.5, 2.
The repository also has docker-compose.yml (prebuilt image) and docker-compose.dev.yml (builds from source). Copy .env.example to .env to configure them.
claude.ai traffic
Every claude.ai user reaches a remote server from Anthropic's outbound range 160.79.104.0/21. That range gets its own rate-limit pool (RATE_LIMIT_ANTHROPIC_RPM) so they don't all share one per-IP budget. Behind a reverse proxy, list the proxy in TRUSTED_PROXIES so the real client IP is seen.
Configuration
All variables are optional.
Server
The cache keeps forecasts and ensembles for 15 minutes, air quality and marine for 30 minutes, flood for 1 hour, seasonal for 6 hours, archive and climate for 24 hours, geocoding for 7 days and elevation for 30 days. Archive ranges ending within the last 5 days are kept for 1 hour only, since Open-Meteo is still backfilling them. Failed requests are never cached.
[!NOTE]
The cache counts serialized JSON, but the parsed objects in memory take about 1.2 to 2.6 times as much. A full cache at the default size costs about 50 MB of heap.
HTTP security
Custom Open-Meteo instance
Each endpoint can be redirected, for example to a self-hosted Open-Meteo:
In Claude Desktop, pass them through the env key of the server entry.
Skills
The skills/ directory holds two SKILL.md guides that help an assistant pick the right tool and parameters:
For Claude Code, copy them to ~/.claude/skills/:
cp -r skills/open-meteo skills/open-meteo-advanced ~/.claude/skills/
For Claude Desktop, upload the relevant SKILL.md into the conversation.
Development
git clone https://github.com/cmer81/open-meteo-mcp.git
cd open-meteo-mcp
npm install
npm run build
To point Claude Desktop at your local build, use "command": "node" with "args": ["/path/to/open-meteo-mcp/dist/index.js"].
Evaluations
evals/evaluation.xml checks whether an LLM given only this server's tools can answer realistic questions. Its 14 questions rely on stable data (ERA5 archive, CMIP6 projections, geocoding, elevation), so the expected answers don't drift.
pip install -r evals/scripts/requirements.txt
export ANTHROPIC_API_KEY=... # or put it in .env
npm run build && npm run eval
npm run eval -- --no-server-instructions # baseline without the server instructions
[!WARNING]
The evaluation calls the real Anthropic API for every question and consumes credits. It is a manual check, not part of CI.
Contributions are welcome: see CONTRIBUTING.md.