Weather MCP Server
by AdhipathiK
README.md
## Overview
This project implements a Model Context Protocol (MCP) server that exposes weather forecast tools, backed by the Open-Meteo API. It can be deployed as a Databricks App and integrated with Agent Bricks to answer natural-language weather questions.
## Architecture
```
┌────────────────────────────────────────────┐
│ Weather MCP Server (Databricks App) │
│ ┌──────────────────────────────────────┐ │
│ │ weather_mcp_server.py │ │
│ │ - FastMCP with @mcp.tool decorators │ │
│ │ - get_current_weather() │ │
│ │ - get_forecast() │ │
│ │ - predict_umbrella_needed() │ │
│ └──────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────┐ │
│ │ weather_broker.py │ │
│ │ - HTTP calls to Open-Meteo API │ │
│ │ - Geocoding (city → lat/lon) │ │
│ │ - Weather code decoding (WMO) │ │
│ │ - Error handling │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
↓ MCP protocol
┌────────────────────────────────────────────┐
│ Agent Bricks Agent │
│ - Uses weather tools via MCP │
│ - Answers natural language questions │
│ - Makes recommendations │
└────────────────────────────────────────────┘
```
## Project Structure
```
weather_mcp_server/
├── weather_mcp_server.py # FastMCP server with tool decorators
├── weather_broker.py # API adapter (HTTP calls, parsing)
├── app.yaml # Databricks App configuration
├── requirements.txt # Python dependencies
└── README.md # This file
```
## MCP Tools (3 Required)
### 1. `get_current_weather(location: str)`
**Purpose**: Fetch real-time weather conditions for any location.
**Arguments**:
- `location` (str): City name or "City, Country" format
**Returns**: JSON with temperature (C/F), conditions, humidity, wind speed, precipitation, cloud cover
**Example**:
```python
get_current_weather("Chicago")
# Returns: {"location": {"name": "Chicago", "country": "United States"},
# "current": {"temperature_c": 22.5, "conditions": "Partly cloudy", ...}}
```
---
### 2. `get_forecast(location: str, days: int = 7)`
**Purpose**: Multi-day weather forecast (1-16 days ahead).
**Arguments**:
- `location` (str): City name
- `days` (int): Number of forecast days (1-16, default 7)
**Returns**: JSON with daily high/low temps, precipitation chance/amount, conditions, wind speed
**Example**:
```python
get_forecast("Seattle", 3)
# Returns: {"location": {...}, "forecast": [
# {"date": "2026-08-09", "temp_max_c": 24.0, "precipitation_chance": 60, ...},
# {...}, {...}
# ]}
```
---
### 3. `predict_umbrella_needed(location: str, date: str = None, threshold_percent: int = 40)`
**Purpose**: Smart recommendation - should you bring an umbrella?
**Arguments**:
- `location` (str): City name
- `date` (str, optional): Target date in "YYYY-MM-DD" format (default: tomorrow)
- `threshold_percent` (int, optional): Precipitation probability threshold (default: 40)
**Decision Logic** (NOT just a passthrough):
- Recommends umbrella if **EITHER**:
1. Precipitation chance > `threshold_percent` (default 40%), OR
2. Expected rainfall >= 2mm
**Returns**: JSON with recommendation, reasoning, forecast details, and decision rule explanation
**Example**:
```python
predict_umbrella_needed("Portland", "2026-08-15")
# Returns: {
# "recommendation": "Yes, bring an umbrella",
# "reasoning": "High chance of rain (65% > 40% threshold) with significant rainfall...",
# "forecast_details": {"precipitation_chance": 65, "precipitation_mm": 4.5, ...},
# "decision_rule": "Umbrella recommended if: (precipitation_chance > 40%) OR (expected_rainfall >= 2mm)"
# }
```
---
## Weather API Details
**API Used**: [Open-Meteo](https://open-meteo.com/en/docs)
**Authentication**: None required (free tier, up to ~10,000 calls/day for non-commercial use)
**Endpoints Used**:
- Geocoding API: `https://geocoding-api.open-meteo.com/v1/search`
- Forecast API: `https://api.open-meteo.com/v1/forecast`
**Why Open-Meteo?**
- No signup or API key required
- Free and reliable
- Returns WMO weather codes (decoded to human-readable strings)
- Supports both current conditions and multi-day forecasts
---
## Setup Instructions
### Step 1: Deploy the MCP Server as a Databricks App
1. **Navigate to Databricks Apps**:
- In your Databricks workspace, go to **Compute** → **Apps**
2. **Create a new app**:
```bash
databricks apps create weather-mcp-server \
--source-code-path /Workspace/Users/<your-email>/weather_mcp_server
```
3. **Deploy the app**:
```bash
databricks apps deploy weather-mcp-server
```
4. **Get the app URL**:
```bash
databricks apps get weather-mcp-server
```
Note the `url` field - you'll need this for Agent Bricks registration.
### Step 2: Register the MCP Server with Agent Bricks
1. **Navigate to Agent Bricks**:
- In Databricks, go to **Machine Learning** → **Agents**
2. **Create a new agent** or **edit an existing one**
3. **Add External Tool**:
- Click "Add Tool" → "External MCP Tool"
- **Tool URL**: `<your-app-url>` (from Step 1)
- **Tool Type**: MCP
4. **Configure System Prompt**:
```
You are a weather assistant powered by real-time weather data.
Available tools:
- get_current_weather(location): Get current conditions
- get_forecast(location, days): Get multi-day forecast (1-16 days)
- predict_umbrella_needed(location, date, threshold_percent): Smart umbrella recommendation
Guidelines:
- Always call tools to get data - never guess or hallucinate weather information
- If a location cannot be found, ask the user to clarify or provide a different location
- For umbrella predictions, explain the reasoning based on the decision rule
- Present temperatures in both Celsius and Fahrenheit
- If an API call fails, inform the user clearly rather than making up data
```
5. **Save and test**!
### Step 3: Test the Agent
Try these example queries:
1. **Current conditions**:
- "What's the weather like in Chicago right now?"
- "Tell me the current temperature in Tokyo"
2. **Forecasts**:
- "Will it rain in Seattle this weekend?"
- "What's the 5-day forecast for Austin?"
3. **Recommendations**:
- "Should I bring an umbrella to Boston tomorrow?"
- "Do I need a jacket in San Francisco on August 12th?"
---
## Key Design Decisions
### 1. **Separation of Concerns**
- `weather_broker.py`: All HTTP calls, geocoding, error handling
- `weather_mcp_server.py`: Thin MCP tool wrappers, JSON serialization
- **Benefit**: MCP tools stay clean and testable; broker can be mocked
### 2. **No Hardcoded Credentials**
- Open-Meteo requires no API key
- If using a different API, follow this pattern:
```python
from databricks.sdk import WorkspaceClient
def _get_api_key():
w = WorkspaceClient()
return w.secrets.get_secret(scope="weather", key="api_key").value
```
### 3. **Error Handling**
- Custom `WeatherBrokerError` exception
- All tools return JSON (never raise exceptions to MCP client)
- Clear error messages: `{"error": "Location 'XYZ' not found"}`
### 4. **Prediction Tool Design**
- **NOT** just a passthrough of raw forecast data
- Applies business logic: `(precip_chance > threshold) OR (precip_mm >= 2mm)`
- Explains reasoning in natural language
- Includes decision rule in output for transparency
---
## Testing Locally (Optional)
You can test the MCP server locally before deploying:
```bash
# Install dependencies
pip install -r requirements.txt
# Run the server
python weather_mcp_server.py
# Server will start on http://localhost:8000
# Use MCP client or curl to test tools
```
---
## Example Agent Interactions
### Example 1: Current Weather
**User**: "What's the weather in London right now?"
**Agent**:
→ Calls `get_current_weather("London")`
← Returns: `{"current": {"temperature_c": 18.5, "temperature_f": 65.3, "conditions": "Partly cloudy", ...}}`
**Response**: "In London, it's currently 18.5°C (65.3°F) with partly cloudy skies. Humidity is at 72%, and winds are light at 12 km/h."
---
### Example 2: Forecast Query
**User**: "Will it rain in Portland this week?"
**Agent**:
→ Calls `get_forecast("Portland", 7)`
← Returns: `{"forecast": [{"date": "2026-08-09", "precipitation_chance": 65, ...}, ...]}`
**Response**: "Looking at Portland's 7-day forecast, rain is likely on:
- **Aug 9**: 65% chance, 4.5mm expected (Moderate rain)
- **Aug 11**: 40% chance, 2.1mm expected (Light rain showers)
The rest of the week looks mostly dry!"
---
### Example 3: Umbrella Recommendation
**User**: "Should I bring an umbrella to Austin tomorrow?"
**Agent**:
→ Calls `predict_umbrella_needed("Austin", "tomorrow")`
← Returns: `{"recommendation": "No umbrella needed", "reasoning": "Low precipitation chance (15% <= 40% threshold) and minimal expected rainfall (0.2mm < 2mm)..."}`
**Response**: "**No umbrella needed** for Austin tomorrow (Aug 9)! There's only a 15% chance of rain with minimal expected rainfall (0.2mm). Conditions will be mainly clear with highs of 34°C (93°F)."
---
## Stretch Features (Not Implemented, Ideas for Extra Credit)
1. **Severe weather alerts** (using NWS API for US locations)
2. **Historical weather lookup** ("What was the weather in NYC last Christmas?")
3. **Multi-city comparison** ("Which is warmer this weekend, Miami or LA?")
4. **Packing recommendations** ("What should I pack for a trip to Iceland next week?")
5. **Dashboard app** showing recent agent queries and predictions
---
## Troubleshooting
**Problem**: "Location 'XYZ' not found"
**Solution**: Try a more specific location (e.g., "Springfield, Illinois" instead of "Springfield")
**Problem**: MCP tools not showing up in Agent Bricks
**Solution**: Verify the app is deployed and the URL is correct. Check app logs: `databricks apps logs weather-mcp-server`
**Problem**: "Forecast API error: timeout"
**Solution**: Open-Meteo may be temporarily unavailable. Retry after a minute.
---
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues