Weather-Prediction MCP Server

Weather-Prediction MCP Server

A weather MCP server that provides current conditions, forecasts, and prediction tools (umbrella, travel recommendations) so agents can answer natural-language weather questions.

Category
Visit Server

README

Weather-Prediction MCP Server + Agent Bricks Agent

A weather MCP server built with FastMCP that exposes weather-forecast tools to a Databricks Agent Bricks agent, so the agent can answer natural-language weather questions and make simple predictions/recommendations (e.g. "Will it rain in Chicago tomorrow?", "Should I bring a jacket to Austin this weekend?").

Built as a homework for Day 3 (Agent Bricks + Alpaca paper-trading MCP server), using that repo's mcp_server/ split as the reference pattern: thin @mcp.tool functions on top of a separate adapter module that owns all the HTTP/parsing.

Live deployment

Two Databricks Apps (mirroring Day 3's server + agent split):

App Role URL
mcp-weather-server MCP server (the 5 tools) https://mcp-weather-server-7474650707148987.aws.databricksapps.com
agent-weather-app The agent (chat UI, calls the MCP tools) https://agent-weather-app-7474650707148987.aws.databricksapps.com
  • MCP endpoint (what the agent connects to): https://mcp-weather-server-7474650707148987.aws.databricksapps.com/mcp
  • Confirmed running from the server logs: Starting MCP server 'weather-prediction' with transport 'http' on http://0.0.0.0:8000/mcp. (Opening /mcp in a browser returns Not Acceptable: Client must accept text/event-stream — that's expected; only an MCP client can speak to it.)
  • agent-weather-app declares mcp-weather-server as an app resource, and its service principal has CAN_USE on the server, so the agent can call all 5 tools.

Weather API + auth

Open-Meteo — chosen because it needs no signup, no API key, and no credit card (free for non-commercial use, ~10k calls/day). Two key-less endpoints are used:

  • Geocoding API (geocoding-api.open-meteo.com) — turns a city name into latitude/longitude.
  • Forecast API (api.open-meteo.com) — current conditions + daily forecast.

Because there are no credentials, there is no Databricks secret to manage for this project. (If you swap in a keyed provider like WeatherAPI.com, fetch the key in weather_adapter.py via WorkspaceClient().secrets.get_secret() — the same pattern as Day 3's alpaca_broker.py — and nothing else changes.)

Architecture

Agent Bricks agent  --(MCP tool calls, streamable HTTP)-->  weather_mcp_server.py
        |                                                            |
        | natural-language weather Q&A                               | (thin @mcp.tool funcs)
        v                                                            v
   final answer  <----------------------------------------  weather_adapter.py
                                                                     |
                                                                     | (all HTTP + parsing)
                                                                     v
                                                       Open-Meteo geocoding + forecast APIs
  • weather_mcp_server.py — FastMCP server; each tool is a thin wrapper that delegates to the adapter and returns a clean dict (or {"status": "error", ...} on failure).
  • weather_adapter.py — the adapter/broker module (like alpaca_broker.py): all requests calls and response parsing live here, plus the WMO weather-code → text mapping. No raw requests calls exist inside any @mcp.tool function.

Tools

Minimum three capabilities (current / forecast / prediction), plus two stretch tools:

Tool Kind What it does
get_current_weather(location) current Temperature, feels-like, humidity, precipitation, wind, conditions for now.
get_forecast(location, days=3) forecast Daily high/low, precip chance & amount, max wind, conditions for the next N days (1–16).
predict_umbrella_needed(location, day_offset=0) prediction Derived yes/no: umbrella if precip chance ≥ 40% or ≥ 0.1 in expected. Returns the reasoning + thresholds.
get_travel_recommendation(location, day_offset=0) prediction Multi-factor packing advice (umbrella / jacket / sunscreen / wind), each with its threshold.
compare_cities_weather(locations, day_offset=0) stretch Side-by-side forecast for several cities + picks the "nicest" via a simple score.

location accepts a city name ("Chicago", "Austin, TX", "London") or a "lat,lon" pair ("41.8781,-87.6298"). day_offset is 0 = today, 1 = tomorrow, etc.

Why the prediction tools aren't just passthroughs

predict_umbrella_needed and get_travel_recommendation apply explicit thresholds (configurable via env vars in app.yaml) to the raw forecast and return the decision plus the reason, rather than echoing the API. Defaults:

Threshold Default Meaning
UMBRELLA_PRECIP_CHANCE_PCT 40 Umbrella if max precip probability ≥ this
UMBRELLA_PRECIP_AMOUNT 0.1 in …or total precip ≥ this
JACKET_TEMP_F 55 Jacket if the day's high ≤ this
SUNSCREEN_TEMP_F 75 Sunscreen if sunny and high ≥ this
WIND_ADVISORY_MPH 25 Wind warning if max wind ≥ this

Error handling & edge cases (with examples)

Every tool catches errors and returns a structured {"status": "error", "message": ...} dict — the MCP-appropriate analog of an HTTP 4xx — so a bad input or an API outage never reaches the agent as a stack trace. Concrete cases:

Input Result Where
Unknown city — get_current_weather("Xyzzyville") {"status":"error","message":"Could not find a location matching 'Xyzzyville'. Try a 'City, ST' form or a 'lat,lon' pair."} adapter raises ValueError (weather_adapter.py:130), tool catches (weather_mcp_server.py:86)
Empty location — get_current_weather("") ValueError("Location is required …") → clean error dict weather_adapter.py:110
Out-of-range daysget_forecast("Chicago", 999) clamped to 1..16 weather_adapter.py:213
Out-of-range day_offsetpredict_umbrella_needed("Chicago", 99) {"status":"error","message":"day_offset 99 is out of range - only N day(s) … (0 = today)."} weather_mcp_server.py:60
Too few cities — compare_cities_weather(["Austin"]) {"status":"error","message":"Provide at least two locations to compare."} weather_mcp_server.py:272
One bad city in a compare that city goes into an errors[] array; the rest still return weather_mcp_server.py:302
API / network outage generic Exception caught + logger.exception(...), returns {"status":"error","message":"Could not fetch …: <e>"} e.g. weather_mcp_server.py:88
lat,lon input — get_current_weather("41.88,-87.63") resolved directly, no geocoding call weather_adapter.py (_LATLON_RE)

Agent behavior on error: the system prompt tells the agent to relay the error and ask the user to clarify rather than guess — see the guardrail screenshot (will it rain? with no location → the agent asks for a location and invents nothing).

Code map (nothing left to inference)

Requirement Exact location
FastMCP + streamable-HTTP transport weather_mcp_server.py:324mcp.run(transport="http", host="0.0.0.0", port=port)
Tools via @mcp.tool (thin wrappers) weather_mcp_server.py lines 69, 93, 117, 186, 252
No raw requests in tools — all HTTP in the adapter weather_adapter.py: _get():95, geocode():100, get_current():151, get_forecast():201. The server imports weather_adapter and never calls requests.
Docstrings (Args/Returns) every tool function in weather_mcp_server.py
Prediction = threshold logic, not a passthrough constants at weather_mcp_server.py:47-51; applied in predict_umbrella_needed:117 and get_travel_recommendation:186; overridable via app.yaml
Clean error handling try/except in every tool; adapter raises typed ValueError with messages
System prompt + guardrails agent/system_prompt.md
No secrets Open-Meteo is key-less; .env git-ignored; no WorkspaceClient().secrets used

This MCP server is stateless — no model or DB loaded per request. The only external calls are two key-less Open-Meteo endpoints, all confined to weather_adapter.py.

Files

  • weather_mcp_server.py — FastMCP server exposing the 5 tools
  • weather_adapter.py — adapter: all Open-Meteo HTTP calls + parsing + WMO code mapping
  • requirements.txt / app.yaml — Databricks App config for the MCP server
  • .env.example — local dev env template (all optional; no key required)
  • agent/system_prompt.md — the Agent Bricks system prompt
  • agent/agent_setup.md — how to register the MCP server + build the agent, and the tool list

Setup

1. Run locally

pip install -r requirements.txt
python weather_mcp_server.py      # serves MCP over streamable HTTP on :8000

Sanity-check the adapter without MCP:

python -c "import json, weather_adapter as w; print(json.dumps(w.get_current('Chicago'), indent=2))"

Or point an MCP Inspector at http://localhost:8000 to list and call the tools.

2. Deploy as a Databricks App

Same flow as Day 3's mcp_server/:

  1. Put this folder in a Databricks Git folder.
  2. Compute > Apps > Create app > Custom, name it e.g. weather-mcp, and point its source at this folder (so it picks up app.yaml).
  3. Deploy, then copy the app URL — you'll register it as an external MCP server next.

No secrets step is needed (Open-Meteo is key-less).

3. Register the MCP server + build the agent

See agent/agent_setup.md for the full steps (mirrors Day 3's README): register the app URL as an external MCP, create an Agent Bricks agent, add the 5 tools, and paste the system prompt from agent/system_prompt.md.

Demonstration (agent Q&A)

Real tool outputs from the live Open-Meteo API (captured 2026-08-09; your numbers will differ):

Q1 — "What's the weather like in Chicago right now?"

Agent calls get_current_weather("Chicago")

{"location": "Chicago, Illinois, United States", "temperature": 83.9, "feels_like": 90.6,
 "humidity_pct": 68, "wind_speed": 11.2, "conditions": "Overcast", "as_of": "2026-08-09T12:15"}

Answer: "Right now in Chicago it's about 84°F (feels like 91°F because of the humidity — 68%), overcast, with an 11 mph wind."

Q2 — "Should I bring an umbrella to Seattle tomorrow?"

Agent calls predict_umbrella_needed("Seattle", day_offset=1)

{"location": "Seattle, Washington, United States", "date": "2026-08-10", "umbrella_needed": false,
 "precip_chance_pct": 2, "conditions": "Overcast",
 "reason": "No umbrella needed. 2026-08-10 in Seattle... only a 2% chance of precipitation... below the 40% / 0.1 in threshold."}

Answer: "No need — tomorrow in Seattle is overcast but only a 2% chance of rain, well below the 40% umbrella threshold."

Q3 — "Should I pack a jacket for Seattle this weekend?"

Agent calls get_travel_recommendation("Seattle", day_offset=1)

{"location": "Seattle, Washington, United States", "date": "2026-08-10",
 "recommendations": ["No special gear needed - mild conditions expected."],
 "forecast": {"temp_high": 74.7, "temp_low": 55.2, "conditions": "Overcast"}}

Answer: "You should be fine without a jacket during the day — highs around 75°F. Evenings dip to the mid-50s, so a light layer wouldn't hurt after sunset."

Q4 (stretch) — "Which has nicer weather this weekend: Austin, Seattle, or Denver?"

Agent calls compare_cities_weather(["Austin","Seattle","Denver"], day_offset=1) → ranks by score and reports the best city with its high/low, conditions, and precip chance.

Notes / guardrails

  • Clean errors, not stack traces. A bad location (get_current_weather("Xyzzy")) returns {"status": "error", "message": "Could not find a location matching 'Xyzzy'. Try a 'City, ST' form or a 'lat,lon' pair."}, and the system prompt tells the agent to ask the user to clarify rather than guess.
  • No hallucinated weather. The system prompt requires the agent to base every weather claim on a tool result and to say so if a tool fails.
  • No secrets committed. Open-Meteo needs none; .env is git-ignored.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured