chuk-mcp-open-meteo 1.0.0
Comprehensive MCP server for Open-Meteo weather data - the best weather MCP server
Requires Python: >=3.11

# Chuk MCP Open-Meteo

**The best weather MCP server ever** - A comprehensive Model Context Protocol (MCP) server for accessing Open-Meteo weather data.

[![PyPI version](https://badge.fury.io/py/chuk-mcp-open-meteo.svg)](https://badge.fury.io/py/chuk-mcp-open-meteo)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

This MCP server provides comprehensive access to Open-Meteo's weather APIs through six powerful tools.

**All tools return fully-typed Pydantic v2 models** for type safety, validation, and excellent IDE support. Every model includes rich, LLM-friendly field descriptions with interpretation guides for better AI understanding.

### 1. Weather Forecast (`get_weather_forecast`)
Get detailed weather forecasts with customizable parameters:
- Current weather conditions
- Hourly forecasts (up to 16 days)
- Daily forecasts
- 50+ weather variables including temperature, precipitation, wind, humidity, cloud cover, and more
- Multiple units (celsius/fahrenheit, km/h, mph, m/s, knots)
- Automatic timezone detection

### 2. Location Geocoding (`geocode_location`)
Convert location names to coordinates:
- Search for any location worldwide
- Get coordinates, elevation, timezone
- Country and administrative information
- Population data where available
- Multi-language support

### 3. Historical Weather (`get_historical_weather`)
Access historical weather data:
- Data from 1940 onwards (location-dependent)
- Same comprehensive variables as forecasts
- Perfect for climate analysis and trends
- Hourly and daily aggregations

### 4. Air Quality (`get_air_quality`)
Monitor air quality and pollutants:
- PM2.5, PM10 particulate matter
- CO, NO2, SO2, O3 gas concentrations
- European AQI and US AQI indices
- Pollen data (multiple species)
- UV index
- Aerosol optical depth

### 5. Marine Forecast (`get_marine_forecast`)
Get marine weather conditions:
- Wave height, direction, and period
- Wind waves and swell waves separately
- Ocean current velocity and direction
- Up to 16-day forecasts
- Essential for maritime activities
- Field descriptions include wave quality interpretations (0-0.5m calm, 1.5-2.5m moderate, etc.)

### 6. Weather Code Interpretation (`interpret_weather_code`)
Translate numeric weather codes to descriptions:
- Converts WMO weather codes (0-99) to human-readable text
- Includes severity categories (clear, rain, snow, thunderstorm, etc.)
- Helps LLMs explain weather conditions in natural language
- Built-in reference for all standard weather codes

## Installation

### Using uvx (Recommended - No Installation Required!)

The easiest way to use the server is with `uvx`, which runs it without installing:

```bash
uvx chuk-mcp-open-meteo
```

This automatically downloads and runs the latest version. Perfect for Claude Desktop!

### Using uv (Recommended for Development)

```bash
# Install from PyPI
uv pip install chuk-mcp-open-meteo

# Or clone and install from source
git clone https://github.com/chrishayuk/chuk-mcp-open-meteo.git
cd chuk-mcp-open-meteo
uv sync --dev
```

### Using pip (Traditional)

```bash
pip install chuk-mcp-open-meteo
```

## Usage

### With Claude Desktop

#### Option 1: Use the Public Server (Easiest)

Connect to the hosted public server at `weather.chukai.io`:

**MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "weather": {
      "url": "https://weather.chukai.io/mcp"
    }
  }
}
```

#### Option 2: Run Locally with uvx

```json
{
  "mcpServers": {
    "open-meteo": {
      "command": "uvx",
      "args": ["chuk-mcp-open-meteo"]
    }
  }
}
```

#### Option 3: Run Locally with pip

```json
{
  "mcpServers": {
    "open-meteo": {
      "command": "chuk-mcp-open-meteo"
    }
  }
}
```

### Standalone

Run the server directly:

```bash
# With uvx (recommended - always latest version)
uvx chuk-mcp-open-meteo

# With uvx in HTTP mode
uvx chuk-mcp-open-meteo http

# Or if installed locally
chuk-mcp-open-meteo
chuk-mcp-open-meteo http
```

Or with uv/Python:

```bash
# STDIO mode (default, for MCP clients)
uv run chuk-mcp-open-meteo
# or: python -m chuk_mcp_open_meteo.server

# HTTP mode (for web access)
uv run chuk-mcp-open-meteo http
# or: python -m chuk_mcp_open_meteo.server http
```

**STDIO mode** is for MCP clients like Claude Desktop and mcp-cli.
**HTTP mode** runs a web server on http://localhost:8000 for HTTP-based MCP clients.

## Example Usage

Once configured, you can ask Claude questions like:

- "What's the current weather in London?"
- "Give me a 7-day forecast for Tokyo with hourly temperature and precipitation"
- "What was the weather like in New York on July 4th, 2020?"
- "What's the air quality in Los Angeles right now?"
- "What are the wave conditions off the coast of Hawaii?"
- "Find the coordinates for Paris, France"

### Python Examples

Check out the `examples/` directory for runnable Python examples:

```bash
# With uv (recommended)
uv run python examples/example_basic.py
uv run python examples/example_trip_planner.py
uv run python examples/test_mcp_protocol.py

# Or with plain python (if installed)
python examples/example_basic.py
python examples/example_trip_planner.py
python examples/test_mcp_protocol.py

# Run all examples
./examples/test_all.sh
```

See [examples/README.md](examples/README.md) for detailed documentation.

## Tool Reference

All tools return **Pydantic v2 models** with full type safety. When calling from Python, you get clean object access:

```python
from chuk_mcp_open_meteo.server import get_weather_forecast

# Get weather forecast
forecast = await get_weather_forecast(latitude=51.5072, longitude=-0.1276, current_weather=True)

# Access data via typed attributes (not dictionaries!)
if forecast.current_weather:
    temp = forecast.current_weather.temperature  # Type-safe access
    wind = forecast.current_weather.windspeed
```

### get_weather_forecast

Parameters:
```python
{
  "latitude": 51.5072,
  "longitude": -0.1276,
  "temperature_unit": "celsius",  # or "fahrenheit"
  "wind_speed_unit": "kmh",       # or "ms", "mph", "kn"
  "precipitation_unit": "mm",      # or "inch"
  "timezone": "auto",              # or specific timezone
  "forecast_days": 7,              # 1-16
  "current_weather": true,
  "hourly": "temperature_2m,precipitation,wind_speed_10m",
  "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum"
}
```

Returns: `WeatherForecast` Pydantic model

**Popular hourly variables**: `temperature_2m`, `relative_humidity_2m`, `precipitation`, `rain`, `snowfall`, `cloud_cover`, `wind_speed_10m`, `wind_direction_10m`, `pressure_msl`, `visibility`

**Popular daily variables**: `temperature_2m_max`, `temperature_2m_min`, `precipitation_sum`, `rain_sum`, `sunrise`, `sunset`, `wind_speed_10m_max`

### geocode_location

Parameters:
```python
{
  "name": "London",
  "count": 10,        # number of results
  "language": "en"    # language code
}
```

Returns: `GeocodingResponse` Pydantic model

### get_historical_weather

Parameters:
```python
{
  "latitude": 40.7128,
  "longitude": -74.0060,
  "start_date": "2020-01-01",
  "end_date": "2020-01-31",
  "hourly": "temperature_2m,precipitation",
  "daily": "temperature_2m_max,temperature_2m_min"
}
```

Returns: `HistoricalWeather` Pydantic model

### get_air_quality

Parameters:
```python
{
  "latitude": 34.0522,
  "longitude": -118.2437,
  "hourly": "pm10,pm2_5,us_aqi,european_aqi"
}
```

Returns: `AirQualityResponse` Pydantic model

### get_marine_forecast

Parameters:
```python
{
  "latitude": 21.3099,
  "longitude": -157.8581,
  "hourly": "wave_height,wave_direction,wave_period"
}
```

Returns: `MarineForecast` Pydantic model

## Development

### Setup

```bash
# Clone the repository
git clone https://github.com/chrishayuk/chuk-mcp-open-meteo.git
cd chuk-mcp-open-meteo

# Install with uv (recommended)
uv sync --dev

# Or with pip
pip install -e ".[dev]"
```

### Running Tests

```bash
make test              # Run tests (excludes network tests)
make test-cov          # Run tests with coverage
make coverage-report   # Show coverage report

# Run all tests including network tests (requires internet)
pytest tests/          # Run all 19 tests
pytest tests/ -m network  # Run only network tests (5 tests)
```

**Note:** Network tests make real API calls to Open-Meteo and are excluded from CI to avoid flaky builds. They include automatic retry logic for local development.

### Code Quality

```bash
make lint      # Run linters
make format    # Auto-format code
make typecheck # Run type checking
make security  # Run security checks
make check     # Run all checks
```

### Building

```bash
make build         # Build package
make docker-build  # Build Docker image
```

## Deployment

### Fly.io

Deploy to Fly.io with a single command:

```bash
# First time setup
fly launch

# Deploy updates
fly deploy
```

The server will be available via HTTP at your Fly.io URL.

### Docker

```bash
# Build the image
docker build -t chuk-mcp-open-meteo .

# Run the container
docker run -p 8000:8000 chuk-mcp-open-meteo
```

## API Credits

This server uses the free [Open-Meteo API](https://open-meteo.com/). Open-Meteo provides:

- Free access for non-commercial use
- No API key required
- High-resolution weather models
- 25+ global weather models
- Historical data from 1940
- No rate limits for reasonable use

Please consider [supporting Open-Meteo](https://open-meteo.com/en/pricing) if you use this extensively.

## Architecture

Built on top of [chuk-mcp-server](https://github.com/chrishayuk/chuk-mcp-server), this server uses:

- **Fast & Simple**: Decorator-based tool definitions
- **Type-Safe**: Automatic JSON-RPC schema generation from Python type hints
- **Pydantic Native**: All responses use Pydantic v2 models for validation and type safety
- **LLM-Optimized**: Rich field descriptions with interpretation guides embedded in models
  - Wave heights include size categories (calm/small/moderate/large/dangerous)
  - Wave periods include quality ratings (choppy/good/excellent)
  - Weather codes include quick reference in field descriptions
  - Direction fields explain meteorological conventions
  - All measurements include context and safety thresholds
- **Async**: Native async/await support for optimal performance
- **Production-Ready**: Sub-3ms latency, 36,000+ RPS capability
- **99% Test Coverage**: Comprehensive test suite ensures reliability

## Public Server

A public instance is hosted at **weather.chukai.io** for easy access:

- **URL**: `https://weather.chukai.io/mcp`
- **Protocol**: MCP over HTTPS
- **Free to use**: No API key required
- **Always up-to-date**: Running the latest version

Simply add it to your Claude Desktop config:

```json
{
  "mcpServers": {
    "weather": {
      "url": "https://weather.chukai.io/mcp"
    }
  }
}
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- [Open-Meteo](https://open-meteo.com/) for providing excellent free weather data
- [Model Context Protocol](https://modelcontextprotocol.io/) for the MCP specification
- [Anthropic](https://www.anthropic.com/) for Claude and MCP support

## Support

- GitHub Issues: [Report bugs or request features](https://github.com/chrishayuk/chuk-mcp-open-meteo/issues)
- Documentation: [Open-Meteo API Docs](https://open-meteo.com/en/docs)

---

**Made with ❤️ by [Chris Hay](https://github.com/chrishayuk)**