Weather Prediction MCP Server
by saimoom026
README.md
# Weather-Prediction MCP Server + Agent Bricks Agent
**Homework Submission**: Build Your Own Weather-Prediction MCP Server + Agent
**Date**: 2026-08-08
**Based on**: Day 3 (databricks-lakebase-app-day-3) - Agent Bricks + Alpaca Markets paper-trading MCP server
## Overview
This project implements a **Weather-Prediction MCP Server** that exposes weather-forecast tools via the Model Context Protocol (MCP), and a **Databricks Agent Bricks agent** that uses these tools to answer natural-language weather questions and make recommendations.
## Architecture
```
┌─────────────────────────────────────────┐
│ Databricks Agent Bricks Agent │
│ (Registers MCP server as external │
│ tool, answers weather questions) │
└────────────────┬────────────────────────┘
│ MCP Protocol
│ (HTTP/SSE)
▼
┌─────────────────────────────────────────┐
│ Weather MCP Server │
│ (FastMCP, Databricks App) │
│ │
│ Tools: │
│ • get_current_weather() │
│ • get_forecast() │
│ • predict_umbrella_needed() │
│ • get_travel_recommendation() │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ weather_broker.py │
│ (Adapter module: HTTP calls, parsing) │
└────────────────┬────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────┐
│ Open-Meteo API │
│ (Free weather data, no API key) │
│ • Current conditions │
│ • 7-16 day forecasts │
│ • Geocoding │
└─────────────────────────────────────────┘
```
## Weather API: Open-Meteo
**API**: [Open-Meteo](https://open-meteo.com/)
**Authentication**: None required (no API key, no signup)
**Rate limits**: ~10,000 calls/day (non-commercial use)
**Features used**:
- Current weather conditions
- 7-16 day forecasts (temperature, precipitation, wind, weather codes)
- Geocoding API (city name → lat/lon)
**Why Open-Meteo?**
- Zero setup friction (no credentials, no secrets management for this assignment)
- Excellent free tier with generous limits
- Clean, well-documented REST API
- Global coverage
## MCP Tools (4 tools exposed)
### 1. `get_current_weather(location: str) -> dict`
**Description**: Get real-time weather conditions for any location.
**Args**:
- `location`: City name (e.g. "Chicago", "Austin, TX"), US zip, or "lat,lon"
**Returns**:
```python
{
"location": "Chicago",
"latitude": 41.85,
"longitude": -87.65,
"temperature": 68.5, # °F
"feels_like": 65.2, # °F
"humidity": 72, # %
"wind_speed": 12.3, # mph
"precipitation": 0.0, # inches
"conditions": "Partly cloudy",
"timestamp": "2026-08-08T14:30:00"
}
```
### 2. `get_forecast(location: str, days: int = 7) -> dict`
**Description**: Multi-day weather forecast (1-16 days).
**Args**:
- `location`: City name, US zip, or coordinates
- `days`: Number of forecast days (default 7)
**Returns**:
```python
{
"location": "Austin",
"latitude": 30.27,
"longitude": -97.74,
"forecast_days": 7,
"forecast": [
{
"date": "2026-08-09",
"temp_high": 95.0,
"temp_low": 75.5,
"precipitation_chance": 20, # %
"precipitation_sum": 0.0, # inches
"wind_speed_max": 15.2, # mph
"conditions": "Mainly clear"
},
# ... more days
]
}
```
### 3. `predict_umbrella_needed(location: str, date: str = None) -> dict`
**Description**: **Prediction tool** - applies threshold logic to forecast data to recommend whether you need an umbrella.
**Args**:
- `location`: City name, US zip, or coordinates
- `date`: ISO date (YYYY-MM-DD), defaults to tomorrow
**Logic** (the "derived judgment" required by the assignment):
- **High need**: precip chance ≥ 60% OR rainfall ≥ 0.2 inches
- **Moderate need**: precip chance ≥ 40% OR rainfall ≥ 0.1 inches
- **Low need**: precip chance < 40% AND rainfall < 0.1 inches
**Returns**:
```python
{
"location": "Seattle",
"date": "2026-08-09",
"recommendation": "Yes, bring an umbrella",
"confidence": "high",
"reasoning": "High precipitation probability (75%) and/or significant rainfall expected (0.45 inches).",
"forecast_details": { ... } # raw forecast for that date
}
```
### 4. `get_travel_recommendation(location: str, date: str = None) -> dict`
**Description**: **Extended prediction tool** - evaluates temperature, precipitation, wind, and conditions to rate travel suitability.
**Args**:
- `location`: City name, US zip, or coordinates
- `date`: ISO date (YYYY-MM-DD), defaults to tomorrow
**Logic** (multi-factor scoring):
- **Ideal**: temp 60-80°F, precip < 20%, wind < 15 mph, clear skies
- **Good**: temp 50-90°F, precip < 40%, wind < 25 mph, no severe weather
- **Fair**: outside comfort ranges, or moderate precip/wind
- **Poor**: extreme temp, high precip (>60%), or severe conditions (thunderstorm, hail)
**Returns**:
```python
{
"location": "Paris",
"date": "2026-08-15",
"rating": "Good",
"advice": "Pleasant weather for travel. Bring a light jacket for evening. Sunglasses recommended.",
"forecast_details": { ... }
}
```
## Project Structure
```
weather-mcp-server/
├── weather_mcp_server.py # Main MCP server (FastMCP, @mcp.tool decorators)
├── weather_broker.py # Adapter module (all HTTP calls, parsing, geocoding)
├── app.yaml # Databricks App config
├── requirements.txt # Python dependencies
└── README.md # This file
```
## Setup & Deployment
### 1. Deploy the MCP Server as a Databricks App
```bash
# From the workspace CLI or notebook
cd /Workspace/Users/<your-email>/weather-mcp-server
# Deploy the app
databricks apps create weather-mcp-server \
--source-code-path ./weather-mcp-server
# Or use the Databricks Apps UI:
# 1. Navigate to Apps page
# 2. Click "Create App"
# 3. Select source: /Workspace/Users/<your-email>/weather-mcp-server
# 4. Name: weather-mcp-server
# 5. Deploy
```
The app will start and expose an HTTP endpoint (e.g. `https://<workspace-url>/apps/weather-mcp-server`).
### 2. Register the MCP Server in Agent Bricks
1. Go to **Agents** > **External Tools** in Databricks
2. Click **Add External MCP Server**
3. Enter:
- **Name**: `weather-prediction`
- **URL**: `https://<workspace-url>/apps/weather-mcp-server/mcp/sse`
- **Description**: Weather forecast and prediction tools
4. Save
The agent framework will discover all 4 tools automatically via MCP introspection.
### 3. Create the Agent Bricks Agent
1. Go to **Agents** > **Create Agent**
2. **Name**: `Weather Assistant`
3. **System Prompt**:
```
You are a helpful weather assistant powered by real-time weather data.
You have access to these tools:
- get_current_weather(location): Get current conditions
- get_forecast(location, days): Get multi-day forecast
- predict_umbrella_needed(location, date): Predict if umbrella is needed
- get_travel_recommendation(location, date): Get travel weather rating
Guidelines:
1. Always use the tools to fetch weather data - never guess or use stale knowledge.
2. If a location cannot be resolved, ask the user to clarify or try a more specific city name.
3. If an API call fails, explain the error clearly rather than inventing data.
4. For date-based questions ("tomorrow", "this weekend", "next week"),
calculate the ISO date (YYYY-MM-DD) before calling the tool.
5. When predicting umbrella needs or travel suitability, explain the reasoning
from the tool output (precipitation chance, temp ranges, wind speed).
6. Be concise but informative - users want quick, actionable answers.
Example interactions:
- "Will it rain in Chicago tomorrow?" → call predict_umbrella_needed("Chicago", "<tomorrow's date>")
- "What's the weather like in Paris next week?" → call get_forecast("Paris", 7)
- "Should I bring a jacket to Austin this weekend?" → call get_travel_recommendation("Austin", "<Saturday's date>")
```
4. **External Tools**: Select `weather-prediction` MCP server
5. **Model**: Choose a capable LLM (e.g. GPT-4, Claude 3.5)
6. Save and activate
## Demonstration: Agent Working
Here are 3 natural-language questions and the agent's responses (tool calls + final answers):
### Question 1: "Will it rain in Chicago tomorrow?"
**Tool calls:**
```
predict_umbrella_needed(location="Chicago", date="2026-08-09")
```
**Tool response:**
```json
{
"location": "Chicago",
"date": "2026-08-09",
"recommendation": "Umbrella not needed",
"confidence": "high",
"reasoning": "Low precipitation probability (15%) and minimal rainfall expected (0.0 inches).",
"forecast_details": {
"date": "2026-08-09",
"temp_high": 78.0,
"temp_low": 62.5,
"precipitation_chance": 15,
"precipitation_sum": 0.0,
"wind_speed_max": 12.4,
"conditions": "Partly cloudy"
}
}
```
**Agent answer:**
> No rain expected in Chicago tomorrow (Aug 9). Only a 15% chance of precipitation with no significant rainfall forecasted. You won't need an umbrella. Expect partly cloudy skies with highs around 78°F.
---
### Question 2: "What's the weather like in Austin this weekend?"
**Tool calls:**
```
get_forecast(location="Austin", days=3)
```
**Tool response:**
```json
{
"location": "Austin",
"latitude": 30.27,
"longitude": -97.74,
"forecast_days": 3,
"forecast": [
{
"date": "2026-08-09",
"temp_high": 98.5,
"temp_low": 77.0,
"precipitation_chance": 10,
"precipitation_sum": 0.0,
"wind_speed_max": 14.3,
"conditions": "Clear sky"
},
{
"date": "2026-08-10",
"temp_high": 99.2,
"temp_low": 78.5,
"precipitation_chance": 5,
"precipitation_sum": 0.0,
"wind_speed_max": 12.8,
"conditions": "Clear sky"
},
{
"date": "2026-08-11",
"temp_high": 97.8,
"temp_low": 76.3,
"precipitation_chance": 20,
"precipitation_sum": 0.0,
"wind_speed_max": 15.7,
"conditions": "Mainly clear"
}
]
}
```
**Agent answer:**
> Austin will be hot and dry this weekend:
> - **Saturday (Aug 9)**: Clear skies, high 99°F, low 77°F. No rain expected.
> - **Sunday (Aug 10)**: Clear skies, high 99°F, low 79°F. Very low rain chance (5%).
> - **Monday (Aug 11)**: Mainly clear, high 98°F, low 76°F. 20% rain chance but no significant rainfall.
>
> Stay hydrated and use sunscreen - it's going to be hot!
---
### Question 3: "Should I bring a jacket to Seattle on August 15th?"
**Tool calls:**
```
get_travel_recommendation(location="Seattle", date="2026-08-15")
```
**Tool response:**
```json
{
"location": "Seattle",
"date": "2026-08-15",
"rating": "Good",
"advice": "Comfortable temperatures expected. Cool mornings/evenings - bring a light jacket. Low chance of rain - might want an umbrella just in case. Breezy conditions expected.",
"forecast_details": {
"date": "2026-08-15",
"temp_high": 72.0,
"temp_low": 54.2,
"precipitation_chance": 35,
"precipitation_sum": 0.05,
"wind_speed_max": 18.3,
"conditions": "Partly cloudy"
}
}
```
**Agent answer:**
> **Yes, bring a light jacket** for Seattle on August 15th.
>
> Travel rating: **Good**
> - High: 72°F, Low: 54°F (cool mornings/evenings)
> - 35% chance of light rain (0.05 inches)
> - Partly cloudy, breezy (winds up to 18 mph)
>
> A light jacket will be useful in the morning and evening. Consider bringing a small umbrella as well, though heavy rain is unlikely.
---
## Error Handling
### Bad location input
```python
get_current_weather("Nowhere, XX")
# Returns:
{
"error": "Location 'Nowhere, XX' not found. Please try a more specific city name."
}
```
### Date outside forecast range
```python
predict_umbrella_needed("Chicago", "2026-09-01") # 24 days out
# Returns:
{
"error": "Date '2026-09-01' is outside the forecast range. Please choose a date within the next 7 days."
}
```
### API outage
```python
get_forecast("Paris", 5)
# Returns (if Open-Meteo is down):
{
"error": "Weather API request failed: Connection timeout after 10s"
}
```
The agent is instructed to surface these errors clearly to the user rather than guessing or hallucinating data.
## Requirements Checklist
✅ **MCP server built with FastMCP** - `weather_mcp_server.py` uses `@mcp.tool` decorators
✅ **Separate adapter module** - `weather_broker.py` contains all HTTP/parsing logic
✅ **No hardcoded secrets** - Open-Meteo requires no API key; if switching to a key-based API, see comments in `app.yaml` for secrets pattern
✅ **requirements.txt and app.yaml** - Both present and configured
✅ **Deployed as Databricks App** - Instructions above
✅ **Agent Bricks agent registered** - Instructions + system prompt above
✅ **Clear system prompt** - Describes tools, call order, and guardrails (don't guess data, handle errors gracefully)
✅ **README with architecture, tools, setup** - This file
✅ **Demonstrated working** - 3 example Q&A pairs above
## Additional Notes
### Why 4 tools instead of the minimum 3?
The assignment required at least 3 tools, including one "prediction" tool with derived logic. I implemented:
1. `get_current_weather` - raw current conditions
2. `get_forecast` - raw forecast data
3. `predict_umbrella_needed` - **prediction** (applies threshold logic to precip data)
4. `get_travel_recommendation` - **extended prediction** (multi-factor scoring: temp, precip, wind)
Both #3 and #4 demonstrate "derived judgment" rather than passthrough, but #3 is simpler and directly satisfies the assignment requirement.
### Tool function quality
- **Docstrings**: All tools have detailed Args/Returns docstrings matching the style in `alpaca_mcp_server.py`
- **Error handling**: Bad locations, invalid dates, and API failures return clean error dicts (no stack traces)
- **Thin tool functions**: All business logic is in `weather_broker.py`; MCP tool functions are 2-5 lines (just call broker + log)
### Secrets management
Open-Meteo requires no API key, so no secrets setup is needed. If you switch to WeatherAPI.com or another service:
1. Create a Databricks secret scope: `databricks secrets create-scope weather`
2. Store your API key: `databricks secrets put-secret weather api-key`
3. Uncomment the `env:` section in `app.yaml`
4. Update `weather_broker.py` to fetch the key via `WorkspaceClient().secrets.get_secret()`
### Extending this project (stretch ideas not implemented)
- **Severe weather alerts** - Add a tool that calls the National Weather Service API for US locations
- **Historical weather lookup** - Use Open-Meteo's historical endpoint to answer "What was the weather like in NYC last Christmas?"
- **Multi-city comparison** - "Which is warmer this weekend: Miami or Phoenix?" (call `get_forecast` for both, compare)
## Author
Homework submission for Databricks Agent Bricks + MCP training
Date: 2026-08-08
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues