Skip to main content
Glama
weather-mcp
by Z4D4LY

weather-mcp

An MCP server that gives any AI client live weather, sea, and news data for any place on Earth — free, with no API keys and no signup.

Model Context Protocol server (stdio transport) exposing five tools. Ask an AI assistant about a city and it calls these tools to fetch real, up-to-the-minute data instead of guessing.

  • šŸ†“ Zero running cost — Open-Meteo and RSS need no keys or accounts.

  • šŸŒ Any location — geocoding by name, worldwide.

  • šŸŒ”ļø Metric or imperial — one units parameter across every tool.

  • 🧭 Weather, sea, and news — current conditions, multi-day forecast, wave height/period, and headlines.

  • šŸ Minimal — one dependency (mcp), pure standard library for everything else.


Table of contents


Related MCP server: WeatherTrax MCP Server

Why this exists

Without MCP, every AI app needs custom glue code for every data source. With MCP, a data source is written once as a server, and every compatible client can use it. This project is a small, complete, dependency-light example of that pattern: five tools, three free data sources, no keys, no bill.

The same skeleton applies to any data you want an assistant to reach — point a tool at your notes file, database, or API and nothing else changes.


Tools

Tool

What it returns

geocode(city)

Latitude, longitude, country, timezone for a place name

get_weather(city, units)

Current temperature, feels-like, humidity, wind + gusts, UV index + risk, conditions

get_forecast(city, days, units)

Per-day min/max temp, mean humidity, max wind + gusts, max UV + risk, sunrise/sunset, rain chance

get_marine(city, units)

Wave height, period (s), direction (degrees + compass) — coastal places only

get_news(city, limit, query)

Recent headlines: title, source, published date, link

Every tool returns JSON. If something goes wrong (unknown place, no network, inland marine), it returns a friendly {"error": "..."} object instead of crashing.


Quick start

Requires Python 3.10+ and network access.

git clone https://github.com/z4d4ly/weather-mcp.git
cd weather-mcp

python3 -m venv .venv
./.venv/bin/pip install -e .      # or: ./.venv/bin/pip install -r requirements.txt

Run the server (it speaks MCP over stdio, so it waits for a client):

./.venv/bin/python server.py
# or, once installed:  ./.venv/bin/weather-mcp

Verify it works end to end against the live APIs:

./.venv/bin/python smoke_test.py

Connect an AI client

Point the client at the Python interpreter and server.py. Use absolute paths on your own machine — replace <path-to-weather-mcp> below.

OpenCode (V2)

Add it with the CLI:

opencode mcp add weather --global -- \
  <path-to-weather-mcp>/.venv/bin/python <path-to-weather-mcp>/server.py

Or in ~/.config/opencode/opencode.jsonc:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "weather": {
        "type": "local",
        "command": [
          "<path-to-weather-mcp>/.venv/bin/python",
          "<path-to-weather-mcp>/server.py"
        ]
      }
    }
  }
}

Claude Desktop

In claude_desktop_config.json:

{
  "mcpServers": {
    "weather": {
      "command": "<path-to-weather-mcp>/.venv/bin/python",
      "args": ["<path-to-weather-mcp>/server.py"]
    }
  }
}

Cursor

In .cursor/mcp.json (or the global equivalent):

{
  "mcpServers": {
    "weather": {
      "command": "<path-to-weather-mcp>/.venv/bin/python",
      "args": ["<path-to-weather-mcp>/server.py"]
    }
  }
}

Any other client

It is a standard stdio MCP server: launch it as python server.py and speak MCP over stdin/stdout.


Example prompts and results

Real outputs, trimmed for length.

"What's the weather in Casablanca right now?"

{
  "city": "Casablanca", "country": "Morocco",
  "temperature": 22.0, "feels_like": 22.3,
  "humidity_pct": 54, "wind": 2.3, "wind_gusts": 12.2,
  "uv_index": 3.2, "uv_risk": "moderate",
  "conditions": "mainly clear",
  "units": { "temperature": "°C", "wind": "km/h" },
  "observed_at": "2026-11-07T10:15"
}

"Give me a 3-day forecast for Marrakesh in Fahrenheit."

{
  "city": "Marrakesh", "country": "Morocco",
  "units": { "temperature": "°C", "wind": "km/h" },
  "forecast": [
    { "date": "2026-11-07", "temp_min": 15.0, "temp_max": 27.6,
      "humidity_mean_pct": 62, "wind_max": 6.7, "wind_gusts_max": 19.4,
      "uv_index_max": 5.15, "uv_risk": "moderate",
      "sunrise": "2026-11-07T06:53", "sunset": "2026-11-07T17:38",
      "rain_chance_pct": 0 },
    { "date": "2026-11-08", "temp_min": 16.3, "temp_max": 28.1,
      "humidity_mean_pct": 59, "wind_max": 10.5, "wind_gusts_max": 27.7,
      "uv_index_max": 4.6, "uv_risk": "moderate",
      "sunrise": "2026-11-08T06:54", "sunset": "2026-11-08T17:37",
      "rain_chance_pct": 40 }
  ]
}

"Are the waves any good in Casablanca?"

{
  "city": "Casablanca", "country": "Morocco",
  "wave_height": 0.64, "wave_period_s": 10.8,
  "wave_direction_deg": 311, "wave_direction_compass": "NW",
  "units": { "wave_height": "m" },
  "observed_at": "2026-11-07T11:15"
}

"Waves in Marrakesh?" (inland — handled gracefully)

{
  "city": "Marrakesh", "country": "Morocco",
  "error": "No sea near Marrakesh — the marine model has no data here."
}

"Latest news about Rabat."

{
  "city": "Rabat", "country": "Morocco",
  "query": "\"Rabat\" Morocco",
  "count": 2,
  "articles": [
    { "title": "Morocco's Rabat festival showcases work of six women directors",
      "source": "Muslim Network TV",
      "published": "Sat, 07 Nov 2026 00:47:35 GMT",
      "link": "https://news.google.com/rss/articles/..." },
    { "title": "Spain Visa: BLS Rabat Permits Filing Without an Appointment ...",
      "source": "Morocco World News",
      "published": "Fri, 06 Nov 2026 20:20:58 GMT",
      "link": "https://news.google.com/rss/articles/..." }
  ]
}

Units

get_weather, get_forecast, and get_marine accept units:

units

Temperature

Wind

Wave height

"metric" (default)

°C

km/h

m

"imperial"

°F

mph

ft

Unknown values fall back to metric.


Data sources, cost, and privacy

Data

Source

Key required?

Geocoding

Open-Meteo Geocoding API

No

Weather & forecast

Open-Meteo Forecast API

No

Marine / waves

Open-Meteo Marine API

No

News

Google News RSS

No

  • Cost: nothing. There is no paid tier, no API key, and no quota to configure.

  • Privacy: the only data leaving your machine is the place name you search for. No accounts, no telemetry, no analytics.

  • Rate limits: Open-Meteo is free for non-commercial use with fair-use limits; be a good citizen and avoid hammering it in tight loops.


The news caveat

get_news reads Google News RSS. Google's feed states it is for personal, non-commercial use. That makes it fine for local demos and personal tools, but do not ship a public or commercial product on it without switching to a source whose terms allow it (for example, an outlet's own RSS feed).

The news code is deliberately isolated in one function (get_news) so it can be swapped without touching anything else.

By default the tool searches the city within its country (e.g. "Casablanca" Morocco) and keeps only headlines that mention the city. This filters out unrelated hits such as the "Casablanca Records" label or the 1942 film. Pass query to override the search entirely.


Development

Unit tests (offline, milliseconds):

./.venv/bin/python -m unittest discover -s tests -v

Live smoke test (network, exercises every tool + error paths, exits non-zero on failure):

./.venv/bin/python smoke_test.py

The unit tests cover the pure helpers (unit conversion, compass mapping, UV bands, input clamping). The smoke test drives the server over stdio exactly as a real client would.


Project layout

weather-mcp/
ā”œā”€ā”€ server.py            # the MCP server: helpers, HTTP, and the five tools
ā”œā”€ā”€ smoke_test.py        # live end-to-end test over stdio
ā”œā”€ā”€ tests/
│   └── test_server.py   # offline unit tests (stdlib unittest)
ā”œā”€ā”€ pyproject.toml       # packaging metadata + console script
ā”œā”€ā”€ requirements.txt     # one-line dependency list
ā”œā”€ā”€ .gitignore
ā”œā”€ā”€ LICENSE              # MIT
└── README.md

Notes

  • Requires mcp v2. In v2 the server class was renamed FastMCP → MCPServer (from mcp.server import MCPServer). Many older tutorials still show FastMCP and will not run against v2.

  • Open-Meteo's geocoder uses the English spelling "Marrakesh", not the French "Marrakech".


License

MIT.

Related MCP Connectors

Related MCP Servers