Skip to main content
Glama
abdoukaba
by abdoukaba
README.md
# Weather MCP Server

A production-ready Model Context Protocol (MCP) server that provides real-time weather information to LLM clients using the Open-Meteo API. http://ec2-35-180-66-133.eu-west-3.compute.amazonaws.com:3000/weather-dashboard.html

## Features

- **Current Weather**: Get real-time weather conditions including temperature, humidity, wind, and more
- **Weather Forecasts**: Up to 16-day forecasts with detailed daily breakdowns
- **Weather Alerts**: Automated detection of severe weather conditions
- **26+ Global Cities**: Pre-configured major cities across all continents
- **Dual Transport**: Supports both STDIO (local) and HTTP (production) transports
- **Docker Ready**: Production-grade containerization with health checks
- **Type Safe**: Full type hints and validation
- **No API Key Required**: Uses free Open-Meteo API

## Quick Start

### Local Development (STDIO)

1. **Install dependencies:**
```bash
pip install -r requirements.txt
```

2. **Run the server:**
```bash
python server.py --stdio
```

3. **Configure Claude Desktop:**
Edit your Claude Desktop configuration file and add:
```json
{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": [
        "/absolute/path/to/weather_mcp_server/server.py",
        "--stdio"
      ],
      "env": {
        "MCP_TRANSPORT": "stdio",
        "PYTHONUNBUFFERED": "1"
      }
    }
  }
}
```

### Production Deployment (Docker)

1. **Build and run with Docker Compose:**
```bash
docker-compose up -d
```

2. **Check health:**
```bash
curl http://localhost:3000/health
```

3. **Access MCP endpoint:**
```bash
curl http://localhost:3000/mcp
```

## Available Tools

### `get_current_weather(city: str)`
Get current weather conditions for a city.

**Example:**
```python
{
  "city": "london",
  "temperature": {"value": 15.2, "unit": "°C", "feels_like": 13.8},
  "conditions": "Partly cloudy",
  "humidity": {"value": 72, "unit": "%"},
  "wind": {"speed": 12.5, "speed_unit": "km/h", "direction": 245}
}
```

### `get_forecast(city: str, days: int = 7)`
Get weather forecast for 1-16 days.

**Parameters:**
- `city`: City name (e.g., "paris", "new_york")
- `days`: Number of days (1-16, default: 7)

**Example:**
```python
{
  "city": "Paris",
  "forecast_days": 7,
  "forecast": [
    {
      "date": "2025-01-20",
      "conditions": "Partly cloudy",
      "temperature": {"max": 18.5, "min": 12.3, "unit": "°C"},
      "precipitation": {"total": 2.5, "probability": 30, "unit": "mm"}
    }
  ]
}
```

### `get_weather_alerts(city: str)`
Get weather alerts and warnings for a city.

**Example:**
```python
{
  "city": "Miami",
  "alert_count": 2,
  "alerts": [
    {
      "type": "High Wind Warning",
      "severity": "moderate",
      "description": "Strong winds detected: 55 km/h"
    }
  ]
}
```

## Available Resources

### `weather://cities/supported`
Returns list of all supported cities with coordinates.

### `weather://api/info`
Returns information about the Open-Meteo API and its capabilities.

### `health://status`
Health check endpoint for monitoring.

## Supported Cities

The server includes 26 major cities across 6 continents:

**North America:** New York, Los Angeles, Chicago, San Francisco, Toronto, Vancouver, Mexico City

**Europe:** London, Paris, Berlin, Madrid, Rome, Amsterdam

**Asia:** Tokyo, Beijing, Shanghai, Singapore, Seoul, Mumbai, Dubai

**Oceania:** Sydney, Melbourne, Auckland

**South America:** São Paulo, Buenos Aires, Rio de Janeiro

**Africa:** Cairo, Cape Town

## Configuration

### Environment Variables

```bash
# Server Configuration
MCP_TRANSPORT=http          # stdio or http
MCP_HOST=0.0.0.0           # Bind address
MCP_PORT=3000              # Server port
MCP_PATH=/mcp              # HTTP endpoint path

# Python Configuration
PYTHONUNBUFFERED=1
PYTHONDONTWRITEBYTECODE=1

# Logging
LOG_LEVEL=INFO             # DEBUG, INFO, WARNING, ERROR, CRITICAL
```

### Docker Configuration

The `docker-compose.yml` includes:
- Resource limits (1 CPU, 512MB RAM)
- Health checks every 30 seconds
- Automatic restart policy
- Security hardening (read-only filesystem, non-root user)
- JSON logging with rotation

## Architecture

```
weather_mcp_server/
├── weather_mcp/
│   ├── __init__.py       # Package initialization
│   ├── server.py         # MCP server with tools & resources
│   ├── api.py            # Open-Meteo API client
│   └── cities.py         # City database
├── tests/
│   └── test_weather.py   # Comprehensive test suite
├── server.py             # Main entry point
├── Dockerfile            # Multi-stage production build
├── docker-compose.yml    # Orchestration with health checks
├── requirements.txt      # Python dependencies
├── nginx.conf            # Optional reverse proxy config
└── README.md             # This file
```

## Development

### Running Tests

```bash
# Install dev dependencies
pip install pytest pytest-asyncio

# Run tests
pytest tests/ -v
```

### Adding New Cities

Edit `weather_mcp/cities.py`:

```python
SUPPORTED_CITIES = {
    "your_city": {
        "lat": 40.7128,
        "lon": -74.0060,
        "name": "Your City",
        "country": "Country",
        "timezone": "America/New_York"
    }
}
```

### Custom Logging

For STDIO transport, logs go to stderr. For HTTP transport, logs are JSON formatted to stdout.

## API Reference

### Open-Meteo API

- **Base URL:** https://api.open-meteo.com/v1/forecast
- **Documentation:** https://open-meteo.com/en/docs
- **Rate Limits:** 10,000 requests/day (free tier)
- **No API key required**

### Data Sources

Open-Meteo aggregates data from multiple weather services:
- NOAA GFS & HRRR (US)
- DWD ICON (Germany)
- Météo-France ARPEGE & AROME (France)

## Deployment Options

### 1. Local Development
```bash
python server.py --stdio
```

### 2. Docker (Single Container)
```bash
docker build -t weather-mcp .
docker run -p 3000:3000 weather-mcp
```

### 3. Docker Compose (Recommended)
```bash
docker-compose up -d
```

### 4. Production with Nginx
```bash
docker-compose --profile production up -d
```

## Monitoring

### Health Check
```bash
curl http://localhost:3000/health
```

### Docker Health Status
```bash
docker ps
# Look for "(healthy)" status
```

### Logs
```bash
# Docker logs
docker logs weather-mcp-server

# Follow logs
docker logs -f weather-mcp-server
```

## Security Features

-  Non-root user execution
-  Read-only root filesystem
-  No new privileges allowed
-  Resource limits enforced
-  Health monitoring
-  No hardcoded credentials
-  Multi-stage Docker build
-  Security updates applied

## Troubleshooting

### Issue: "City not supported"
**Solution:** Check available cities with the `weather://cities/supported` resource or see the list above.

### Issue: Container not healthy
**Solution:** Check logs with `docker logs weather-mcp-server` and ensure port 3000 is available.

### Issue: API timeout
**Solution:** Check internet connectivity and Open-Meteo API status at https://open-meteo.com

### Issue: STDIO not working with Claude Desktop
**Solution:** Ensure absolute path is used in config and Python is in PATH.

## Performance

- **Average response time:** < 500ms
- **Memory footprint:** ~100MB
- **CPU usage:** < 5% under normal load
- **Concurrent requests:** Up to 100 (configurable)

## License

MIT License - Feel free to use in your own projects

## Contributing

Contributions welcome! Areas for improvement:
- Additional cities
- More weather metrics
- Caching layer
- Historical weather data
- Weather maps/visualizations

## Support

For issues or questions:
1. Check the troubleshooting section
2. Review Open-Meteo documentation
3. Open an issue on the repository

## Changelog

### Version 1.0.0 (2025-01-19)
- Initial release
- Current weather, forecasts, and alerts
- 26 supported cities
- Docker containerization
- STDIO and HTTP transports
- Comprehensive test suite