Skip to main content
Glama
madanadi0305

Weather MCP Server

by madanadi0305
README.md
# Weather MCP Server

A Model Context Protocol (MCP) server that exposes weather forecasting tools for Databricks Agent Bricks. Built with FastMCP and OpenMeteo's free weather API.

## Features

### MCP Tools

1. **get_forecast(location, days)** - Get hourly weather forecast for the next X days
   - Temperature, humidity, and wind speed data
   - Returns structured data with coordinates and forecast period

2. **get_current_weather(location)** - Get current weather conditions
   - Real-time temperature, wind speed, and weather conditions
   - Includes location coordinates and timestamp

3. **predict_umbrella_needed(location, date)** - Intelligent umbrella recommendation
   - Analyzes precipitation probability, rainfall amount, and duration
   - Returns YES/MAYBE/NO recommendation with detailed reasoning
   - Includes confidence level (high/medium/low)
  
4. **umbrella prediction logic explanation**
   ## Umbrella Recommendation Logic

The `predict_umbrella_needed` tool uses a multi-factor decision algorithm to recommend whether you should bring an umbrella.

### Thresholds and Decision Factors

| Factor | Threshold | Recommendation |
|--------|-----------|-----------------|
| Precipitation Probability | > 70% | YES (high confidence) |
| Precipitation Probability | 40-70% | YES (medium confidence) |
| Precipitation Probability | < 40% | Contributes to NO |
| **Total Rainfall** | > 5mm | YES (significant rainfall) |
| **Total Rainfall** | 1-5mm | MAYBE (light rain) |
| **Total Rainfall** | < 1mm | Minimal impact |
| **Rain Duration** | > 6 hours | YES (extended period) |
| **Rain Duration** | 2-6 hours | Contributes to decision |
| **Weather Condition** | Rain/Drizzle (WMO 51-67) | YES |
| **Weather Condition** | Thunderstorm (WMO 95-99) | YES (high priority) |
| **Weather Condition** | Snow (WMO 71-86) | MAYBE (umbrella less effective) |

### Decision Algorithm

The tool evaluates all four factors and makes a recommendation:

- **YES - Bring an umbrella ☔**: If any of the following are true:
  - Precipitation probability > 70%
  - Expected rainfall > 5mm
  - Precipitation expected for > 6 hours
  - Rain or thunderstorm detected
  
- **MAYBE - Consider bringing one**: If:
  - Expected rainfall 1-5mm AND precipitation probability 40-70%
  - Snow conditions detected (umbrella may help but not ideal)
  - Borderline conditions between YES and NO
  
- **NO - Umbrella not needed ☀️**: If all factors below thresholds:
  - Precipitation probability < 40%
  - Expected rainfall < 1mm
  - No rain/thunderstorm conditions detected

### Confidence Levels

- **High**: Clear decision based on strong rain signals or confirmed weather codes
- **Medium**: Moderate precipitation probability (40-70%) with moderate rainfall
- **Low**: Marginal or unavailable data; recommendation is less certain

### Example Scenarios

| Scenario | Prob | Rain | Hours | Code | Result |
|----------|------|------|-------|------|--------|
| Sunny day | 10% | 0mm | 0h | Clear | NO ☀️ |
| Light drizzle | 50% | 0.5mm | 2h | Drizzle | YES ☔ (medium confidence) |
| Heavy rain | 85% | 12mm | 8h | Rain | YES ☔ (high confidence) |
| Snow | 60% | 3mm | 4h | Snow | MAYBE ❄️ |
| Thunderstorm | 75% | 8mm | 3h | T-storm | YES ☔ (high priority) |
 
### Additional Features

* **Automatic tracing** - All MCP calls are logged to Lakebase with session IDs, timing, and results
* **User identity tracking** - Captures end-user email from Databricks App headers
* **Error handling** - Comprehensive error handling with structured error responses
* **Geocoding** - Automatic city name to coordinates conversion using OpenStreetMap

## Project Structure

```
weather-mcp-server/
├── mcp_server/
│   ├── openmeteo_mcp_server.py   # FastMCP server with tool definitions
│   ├── openmeteo_broker.py       # Weather API client functions
│   ├── lakebase.py                # Database connection utilities
│   ├── app.yaml                   # Databricks App configuration
│   └── requirements.txt           # Python dependencies

└── README.md                      # This file
```

## Setup

### 1. Install Dependencies

```bash
pip install -r requirements.txt
```

### 2. Configure Environment Variables

Create a `.env` file in the project root:

```bash
LAKEBASE_URL="postgresql://user:password@host.cloud.databricks.com/databricks_postgres?sslmode=require"
```

### 3. Test Locally

```bash
python -m mcp_server.openmeteo_mcp_server
```

The server will start on port 8000 and initialize the `weather_mcp_traces` table in Lakebase.

## Deployment as Databricks App

### Option 1: Using Databricks CLI

```bash
# Ensure LAKEBASE_URL is set in your environment
export LAKEBASE_URL="your-connection-string"

# Deploy the app
databricks apps deploy weather-mcp-server
```

### Option 2: Using Databricks Workspace UI

1. Go to **Apps** in your Databricks workspace
2. Click **Create App**
3. Select this directory: `/Users/madanadi0305@gmail.com/weather-mcp-server`
4. Databricks will automatically detect `app.yaml` and deploy

### Register with Agent Bricks

Once deployed, register the MCP server with your Agent Bricks agent:

1. Get the app URL from the Databricks Apps console
2. In Agent Bricks, add external MCP server:
   - URL: `https://<your-app-url>`
   - Name: `weather-mcp-server`

## Usage Examples

### Get 7-Day Forecast

```python
result = get_forecast("London", 7)
print(result["location"])  # "London"
print(result["coordinates"])  # {"latitude": 51.5074, "longitude": -0.1278}
print(result["data"]["hourly"]["temperature_2m"][0])  # 15.2
```

### Get Current Weather

```python
result = get_current_weather("Tokyo")
current = result["data"]["current_weather"]
print(f"Temperature: {current['temperature']}°C")  # Temperature: 18.5°C
```

### Check If Umbrella Needed

```python
result = predict_umbrella_needed("Seattle", "2024-03-20")
print(result["recommendation"])  # "YES - Bring an umbrella ☔"
print(result["reasoning"])       # "High precipitation probability (85%)..."
print(result["confidence"])      # "high"
```

## Database Schema

The server automatically creates a `weather_mcp_traces` table in Lakebase:

```sql
CREATE TABLE weather_mcp_traces (
    session_id VARCHAR(36) PRIMARY KEY,
    tool_name VARCHAR(100) NOT NULL,
    user_email VARCHAR(255),
    input_params JSONB,
    start_time TIMESTAMP NOT NULL,
    end_time TIMESTAMP,
    duration_ms INTEGER,
    status VARCHAR(20),
    error_message TEXT,
    result_summary JSONB,
    created_at TIMESTAMP DEFAULT NOW()
)
```

## API Documentation

### OpenMeteo API

This server uses two OpenMeteo endpoints:

* **Current Weather**: `https://api.open-meteo.com/v1/forecast`
* **Forecast**: `https://historical-forecast-api.open-meteo.com/v1/forecast`

Both are free and require no API key.

### Geocoding

City-to-coordinates conversion uses OpenStreetMap's Nominatim API:
* **Endpoint**: `https://nominatim.openstreetmap.org/search`
* Free, no API key required
* Respects usage policies with proper User-Agent header

## Development

### Running Tests

```bash
# Test database connection
python mcp_server/lakebase.py

# Test weather API functions
python mcp_server/openmeteo_broker.py
```

### Adding New Tools

To add a new MCP tool:

1. Add the function to `openmeteo_broker.py`
2. Wrap it as an MCP tool in `openmeteo_mcp_server.py`:

```python
@mcp.tool
@trace_mcp_call
def my_new_tool(param: str) -> dict:
    """Tool description for Agent Bricks."""
    return openmeteo_broker.my_new_function(param)
```

## Troubleshooting

### Connection Issues

* Verify `LAKEBASE_URL` is set correctly in `.env`
* Test connection: `python mcp_server/lakebase.py`
* Check firewall/security group settings

### Import Errors

* Ensure all dependencies are installed: `pip install -r requirements.txt`
* Verify you're in the correct directory when running

### MCP Server Not Responding

* Check logs in Databricks Apps console
* Verify port 8000 is accessible
* Test locally first before deploying

## Known Issues




### User Identity Tracking

* The `RequestContextMiddleware` is currently **disabled** due to FastMCP validation issues
* This means `user_email` field in `weather_mcp_traces` table will be NULL
* Impact: Cannot track which end-user made each MCP call
* Status: Investigating FastMCP-compatible middleware approach

### Workaround Options

1. **Add user context to tool parameters**: Modify tools to accept optional `user_email` parameter
2. **Use session-based tracking**: Track sessions instead of individual users
3. **Wait for FastMCP middleware fix**: Monitor FastMCP updates for middleware compatibility

## Performance Notes

* **Geocoding cache**: City-to-coordinates lookups are cached in memory for the app lifetime
* **API rate limits**: OpenMeteo and Nominatim are free services with fair-use policies
* **Database performance**: Each MCP call writes one trace record to Lakebase (async recommended)

## Security Considerations

* **LAKEBASE_URL**: Contains database credentials - keep `.env` file secure and out of version control
* **MCP endpoint**: Publicly accessible at `/mcp` - authentication handled by Databricks Apps OAuth
* **User headers**: The app receives `x-forwarded-email` from Databricks - trust this for identity

## Next Steps

* [ ] Re-enable user tracking with FastMCP-compatible middleware
* [ ] Add caching layer for weather API responses
* [ ] Implement additional weather tools (air quality, UV index, etc.)
* [ ] Add monitoring and alerting for API failures
* [ ] Create automated tests for all three tools

## License

MIT License - see LICENSE file for details

## Contributing

Contributions welcome! Please open an issue or pull request.

## Support

For issues or questions:
* Check the Troubleshooting section above
* Review logs: `databricks apps logs mcp-server-openmeteo-weather`
* Open an issue in the project repository