weather-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@weather-mcpwhat's the weather in Tokyo for the next 3 days?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 |
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 fakedWEATHER_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 |
| — | Bearer required on streamable-http when set. |
| — | Browser-reachable base URL; enables the image card link (HTTP only). |
|
| Where card PNGs are written (served at |
|
| Card link lifetime (seconds). |
| Quito (city-level) | Fallback when a call gives neither place nor coords. Not home coordinates. |
|
| Geocoding language. |
|
| 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-mcpThe 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 toolsgeocodeGeocode placeARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| query | Yes | ||
| language | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds value annotations don't carry: it discloses that multiple candidates are returned and lists their fields, which matters because there is no output schema. It omits failure behavior (no match found) and any rate limiting, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the routing guidance are front-loaded in the first two lines, which is the right ordering. The trailing Args block largely restates the schema's defaults, so it is mildly redundant but still compact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description appropriately describes what comes back (candidate coordinate objects) and documents every parameter. It stops short of covering the no-results or error path, which is the main remaining gap for a lookup tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the schema titles are bare ('Query', 'Count', 'Language'), so the description carries the full burden. It assigns meaning to all three parameters (place name to search, max candidates default 5, result language from config), though the language semantics remain thin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Resolve a place name to candidate coordinates') and enumerates the returned fields (name, admin region, country, lat/lon, timezone). This clearly separates it from the sibling get_forecast, which consumes rather than produces coordinates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the sibling alternative explicitly and gives the selecting condition: 'Use it to disambiguate before get_forecast, or when a user names an ambiguous place.' The agent knows both the trigger and the downstream tool without opening any schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_forecastGet forecastARead-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".
| Name | Required | Description | Default |
|---|---|---|---|
| card | No | auto | |
| days | No | ||
| units | No | metric | |
| language | No | ||
| latitude | No | ||
| location | No | ||
| longitude | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavior beyond that: it explains the dual return shape (structured DATA in the text block plus a `card_markdown` field) and instructs the agent to echo the markdown unchanged, which is non-obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The high-value information (what it returns, and the card_markdown instruction) is front-loaded before the Args block, and each parameter line earns its place. The Args list is somewhat dense but no line is redundant, so it stays efficient for a 7-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the return payload and the card_markdown contract explicitly. Combined with the annotation-covered safety profile and the complete parameter documentation, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden and does so: it documents location vs latitude/longitude precedence, the 1..16 range and default for days, the exact unit systems for metric/imperial, the language parameter's purpose, and all four card modes with fallback behavior. This adds substantial meaning the bare schema lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource — 'Current conditions + an N-day daily forecast for a place' — with explicit scope (current + N-day). It is clearly distinguishable from the sibling geocode tool, which resolves names rather than returning weather.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the precedence rules between location and latitude/longitude and notes the server-default fallback, which is real usage guidance. However, it never states when to use this tool versus the sibling geocode, nor when-not to use it, so an agent must infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
geocode - First observed
get_forecast
TDQS
Scored across 2 tools
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.
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.
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.
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.
Maintenance
Related MCP Connectors
Global weather via Open-Meteo: forecast, historical, marine, air quality, geocoding, elevation.
Current weather and forecasts for any coordinates, backed b… — paid per call (x402/credits), 1 tools
Get current weather for any city and create images from your prompts. Streamline planning, reports…
US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides 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.171,258 npm1MIT
- AlicenseNot gradedqualityDmaintenanceProvides 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
- AlicenseAqualityDmaintenanceProvides weather forecasts and geocoding lookup using free Open-Meteo APIs, enabling LLMs to query real-time weather and multi-day forecasts for any location.18 npmISC
- FlicenseNot gradedqualityCmaintenanceProvides weather forecast tools using Open-Meteo, enabling users to get current conditions, multi-day forecasts, and umbrella recommendations through natural language queries.-