Skip to main content
Glama

weather-mcp

Weather as MCP tools, over Open-Meteo — free, no API key, global. Each forecast returns structured data for the LLM and a weather card for the user: a rendered image (as a short-lived link, not base64), or a monospace text card where no image link can be served, such as over stdio in Claude Code.

Tools

Tool

What it does

get_forecast

Current conditions + an N-day daily forecast for a place (by name or lat/lon). Returns the data as text + a card_markdown for the model to put in its reply. card: auto (default), image, text or none.

geocode

Resolve a place name to candidate coordinates (name, region, country, lat/lon, timezone).

card="auto" gives an image link when the server can serve one (streamable-http with WEATHER_PUBLIC_URL set) and the text card otherwise. A caller whose client doesn't display images from links can ask for card="text" on any transport. The result's card field echoes the form actually returned.

Every result carries a status: ok / refused (caller-fixable input, with advice) / error (a fault). Branch on status, not prose.

Related MCP server: mcp-weather-server

Why it returns an image and data

OpenWebUI's stock weather tool returned only an image — the model got nothing to reason over. This returns the data as text (the model answers from it, even a non-vision local model) and the card as a link the client renders. The image never enters the model's context as bytes (it's an out-of-band capability link, the forge-mcp pattern).

Run

uv sync                      # (--system-certs behind a TLS-inspecting proxy)
# stdio (local MCP client):
uv run weather-mcp serve
# streamable-http (behind mcpo / on the LAN):
WEATHER_MCP_TOKEN=... WEATHER_PUBLIC_URL=http://your-host:8000 \
  uv run weather-mcp serve --transport http --host 0.0.0.0 --port 8000
uv run pytest                # no network: Open-Meteo is faked

WEATHER_PUBLIC_URL must be browser-reachable (the client loads the card) — a LAN name/IP, not an internal container address. Without it, the card is text instead of an image link.

Claude Desktop / Claude Code (stdio)

{
  "mcpServers": {
    "weather": { "command": "uv", "args": ["--directory", "/path/to/weather-mcp", "run", "weather-mcp", "serve"] }
  }
}

Over stdio there is no HTTP server to serve /img/<token>, so the card comes back as monospace text in a ```text fence (WEATHER_PUBLIC_URL is ignored). It renders cleanly in Claude Code's terminal and in Claude Desktop.

Config (env)

Var

Default

Notes

WEATHER_MCP_TOKEN

—

Bearer required on streamable-http when set.

WEATHER_PUBLIC_URL

—

Browser-reachable base URL; enables the image card link (HTTP only).

WEATHER_OUT_DIR

out

Where card PNGs are written (served at /img/<token>, TTL-GC'd).

WEATHER_IMG_TTL

600

Card link lifetime (seconds).

WEATHER_DEFAULT_LAT/LON/NAME

Quito (city-level)

Fallback when a call gives neither place nor coords. Not home coordinates.

WEATHER_LANGUAGE

en

Geocoding language.

WEATHER_HTTP_TIMEOUT

15

Seconds.

Docker

docker build -t weather-mcp .
docker run --rm -p 8000:8000 -e WEATHER_MCP_TOKEN=... -e WEATHER_PUBLIC_URL=http://your-host:8000 weather-mcp

The server is stateless: no database, no volume. Card PNGs are written to WEATHER_OUT_DIR inside the container and expire after WEATHER_IMG_TTL, so losing them on restart is fine. It needs outbound HTTPS to the Open-Meteo API (free for non-commercial use, no key).

Auth and exposure

Auth is deliberately simple: stdio, or streamable-HTTP with a single bearer token (WEATHER_MCP_TOKEN) on a private network, for example behind mcpo. /healthz stays open, and so does /img/*: the client's browser loads the card without the bearer, so each card URL is an unguessable, short-lived capability link instead. There is no OAuth, no users and no audit log, by design. To publish it more widely, put a management layer in front of it: an MCP gateway or auth proxy that handles OAuth, users and audit for all your servers at once.

AI assistance

weather-mcp is developed openly with the help of Claude (Anthropic). Commits Claude helped write carry a Co-Authored-By: Claude trailer. The code and design are open source so the work can be inspected, reused, and given back.

License

MPL-2.0 © Daniel Núñez.

Available Tools

2 tools
geocodeGeocode placeA
Read-onlyIdempotent

Resolve a place name to candidate coordinates (name, admin region, country, lat/lon, timezone). Use it to disambiguate before get_forecast, or when a user names an ambiguous place.

    Args:
        query: the place name to search for.
        count: max candidates to return (default 5).
        language: result language (default from config).
    

Inputs: query (required), count, language.

get_forecastGet forecastA
Read-onlyIdempotent

Current conditions + an N-day daily forecast for a place. Returns the structured DATA in the text block (for you to answer from) and a weather card as card_markdown: include that markdown in your reply, unchanged, so the user sees the card.

    Args:
        location: a place name ("Quito", "Berlin, DE"); geocoded via Open-Meteo. Ignored if
            latitude+longitude are given. With neither, the server's default location is used.
        latitude/longitude: exact coordinates (both required together) — overrides `location`.
        days: number of daily-forecast days, 1..16 (default 3).
        units: "metric" (°C, km/h, mm — default) or "imperial" (°F, mph, in).
        language: language for geocoding the place name (default from config, e.g. "en"/"es").
        card: "auto" (default: an image link when this server can serve one, else a text card),
            "image" (image link; falls back to text when no link can be served), "text" (a monospace
            card in a ```text fence, for terminals or clients that don't show images) or "none".
    

Inputs: card, days, units, language, +3 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 2 tools

    Disambiguation5/5

    get_forecast and geocode have clearly distinct purposes: one fetches weather data, the other resolves place names to coordinates. The get_forecast description even explains when to use geocode first to disambiguate, so there is no realistic misselection risk.

    Naming Consistency4/5

    get_forecast follows a verb_noun pattern, while geocode is a bare verb with no noun. Both are snake_case and readable, so the deviation is minor rather than confusing.

    Tool Count3/5

    Two tools is thin for a weather server; a full forecast surface typically warrants separate helpers (current conditions, hourly, alerts, history). The set is coherent but minimal, and geocode exists mainly as a support tool for get_forecast.

    Completeness4/5

    The forecast tool covers current conditions plus a configurable multi-day daily forecast with units, language, and card rendering, which is the core weather workflow. Gaps remain for hourly forecasts, historical/archive data, and severe-weather alerts, but agents can work around these.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Provides comprehensive access to Open-Meteo weather APIs, including forecasts, historical data, air quality, marine weather, and geocoding, enabling LLMs to retrieve weather information and location data.
      17
      1,730 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides live weather data (current conditions, forecasts) and city geocoding through Open-Meteo API, enabling AI assistants to answer weather queries without an API key.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Provides weather forecasts and geocoding lookup using free Open-Meteo APIs, enabling LLMs to query real-time weather and multi-day forecasts for any location.
      1
      12 npm
      ISC
    • F
      license
      Not graded
      quality
      D
      maintenance
      Provides weather forecast tools using Open-Meteo, enabling users to get current conditions, multi-day forecasts, and umbrella recommendations through natural language queries.
      -