Skip to main content
Glama
adamijjaipro-arch

MCP Weather Server

README.md
# ๐ŸŒค๏ธ MCP Weather Server

A production-grade Model Context Protocol (MCP) server providing comprehensive real-time weather data using the free **Open-Meteo API**.

[![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](https://github.com/your-repo/mcp-weather)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Node.js](https://img.shields.io/badge/node-%3E%3D16.0.0-brightgreen)](package.json)

## โœจ Features

### ๐ŸŒฆ๏ธ Weather Data
- **Current Weather**: Real-time conditions with 20+ meteorological parameters
- **5-Day Forecast**: Detailed daily predictions with solar, UV, and precipitation data
- **Comprehensive Metrics**: Temperature, humidity, wind, pressure, UV index, visibility, cloud cover
- **Solar Data**: Sunshine duration, daylight hours, solar radiation, evapotranspiration

### ๐Ÿš€ Performance & Reliability
- **Redis Caching**: Intelligent caching with configurable TTL (15min current, 1h forecast)
- **Metrics & Monitoring**: Real-time performance tracking and error logging
- **Graceful Degradation**: Continues working without Redis/cache if unavailable
- **Type-Safe**: Full Zod validation for all inputs and API responses

### ๐Ÿ—๏ธ Architecture
- **Multiple Transports**: Stdio (MCP Inspector) + HTTP/SSE streaming
- **Factory Pattern**: Isolated server instances per session
- **Layered Design**: Services, Tools, Server separation
- **ESM Modules**: Modern JavaScript with full ES2022 support

### ๐Ÿ”ง Developer Experience
- **64 Unit Tests**: Comprehensive Jest test suite
- **Hot Reload**: Development mode with file watching
- **Debug Support**: Integrated debugging for both transports
- **Rich Logging**: Structured logs with performance metrics

## ๐Ÿ“Š Data Sources

### Open-Meteo API (Free Tier)
- **No API Key Required** - Unlimited calls for non-commercial use
- **Global Coverage** - Weather models for every location worldwide
- **Multiple Models** - ECMWF, NOAA GFS, Mรฉtรฉo-France, DWD ICON, and more
- **Real-time Updates** - 15-minute to hourly resolution

### Available Weather Variables

#### Current Conditions
- Temperature & "Feels Like" (2m & apparent)
- Humidity, Dew Point, Vapour Pressure Deficit
- Wind Speed/Direction/Gusts (10m, 80m, 120m, 180m altitudes)
- Pressure (MSL & Surface), Cloud Cover (Total/Low/Mid/High)
- Visibility, UV Index, Precipitation
- Evapotranspiration & Reference ETโ‚€

#### Forecast Data
- Daily min/max temperatures (actual & apparent)
- Precipitation (total, rain, showers, snow)
- Wind (speed, gusts, dominant direction)
- Solar (sunrise/sunset, sunshine/daylight duration, UV index)
- Radiation (shortwave solar radiation sum)

## ๐Ÿ›๏ธ Architecture

```
src/
โ”œโ”€โ”€ index.js                    # Entry point & transport orchestration
โ”œโ”€โ”€ server/
โ”‚   โ”œโ”€โ”€ weatherMcpFactory.js    # Server factory with cache init
โ”‚   โ””โ”€โ”€ streamableHttpServer.js # HTTP/SSE transport server
โ”œโ”€โ”€ services/
โ”‚   โ”œโ”€โ”€ weatherApi.js          # Open-Meteo API client with caching
โ”‚   โ”œโ”€โ”€ weatherCodes.js        # WMO weather code mappings
โ”‚   โ”œโ”€โ”€ cache.js               # Redis cache service
โ”‚   โ””โ”€โ”€ metrics.js             # Performance monitoring
โ””โ”€โ”€ tools/
    โ”œโ”€โ”€ schemas.js             # Zod validation schemas
    โ”œโ”€โ”€ getWeatherTool.js      # Current weather MCP tool
    โ”œโ”€โ”€ getWeatherForecast5DaysTool.js # Forecast MCP tool
    โ””โ”€โ”€ getServerStatsTool.js  # Server metrics tool
```

### Design Patterns

| Pattern | Implementation | Purpose |
|---------|---|---|
| **Factory** | `createWeatherMcpServer()` | Isolated server instances per session |
| **Strategy** | Stdio vs HTTP transport strategies | Multiple deployment modes |
| **Adapter** | MCP SDK transport wrapping | Unified interface for different transports |
| **Decorator** | Response formatting with emojis | Enhanced user experience |
| **Observer** | Metrics collection | Performance monitoring |
| **Proxy** | Cache layer | API call optimization |

## ๐Ÿ“‹ Installation

### Prerequisites
- **Node.js** โ‰ฅ16.0.0 (with `--experimental-vm-modules` for Jest)
- **Redis** (optional, for caching) - Install from [redis.io](https://redis.io)

### Setup
```bash
# Clone repository
git clone <repository-url>
cd mcp-weather

# Install dependencies
npm install

# Run tests
npm test

# Start server (stdio mode)
npm start
```

### Environment Variables
```bash
# Redis configuration (optional)
REDIS_URL=redis://localhost:6379

# HTTP server configuration
MCP_HTTP_PORT=3333
MCP_HTTP_HOST=127.0.0.1
```

## ๐Ÿš€ Usage

### MCP Inspector (Recommended)
```bash
# Start in stdio mode for MCP Inspector
npm start

# Then open MCP Inspector and connect to the server
```

### HTTP/SSE Mode
```bash
# Start HTTP server with SSE transport
npm run start:http

# Server runs on http://127.0.0.1:3333
# MCP endpoint: http://127.0.0.1:3333/mcp
```

### Development Mode
```bash
# With hot reload
npm run dev

# With debugging
npm run debug:http  # HTTP mode
npm run debug       # Stdio mode
```

## ๐Ÿ”ง API Reference

### Tools

#### `get_weather`
Get current weather conditions for coordinates.

**Input:**
```json
{
  "latitude": 48.8566,
  "longitude": 2.3522
}
```

**Output:**
```
๐ŸŒค๏ธ Current Weather

๐Ÿ“ Location: 48.8566, 2.3522
๐ŸŒก๏ธ Temperature: 22.5ยฐC (feels like 24.1ยฐC)
๐Ÿ’ง Humidity: 65%
๐ŸŒซ๏ธ Dew Point: 15.8ยฐC
๐Ÿ’จ Wind: 12 km/h from WSW
๐ŸŒช๏ธ Wind Gusts: 18 km/h
โ˜๏ธ Conditions: Partly cloudy
โ˜๏ธ Cloud Cover: 45% (Low: 20%, Mid: 15%, High: 10%)
๐Ÿ‘๏ธ Visibility: 24 km
๐Ÿงญ Pressure: 1013 hPa (MSL) / 1011 hPa (Surface)
โ˜€๏ธ UV Index: 6
๐Ÿ’ง Evapotranspiration: 0.15 mm/h
๐ŸŒฑ Reference ETโ‚€: 0.22 mm/h
๐ŸŒก๏ธ Vapor Pressure Deficit: 0.85 kPa
๐ŸŒ Timezone: Europe/Paris
๐Ÿ• Updated: 2024-03-29T14:30:00Z
```

#### `get_weather_forecast`
Get 5-day weather forecast for coordinates.

**Input:**
```json
{
  "latitude": 48.8566,
  "longitude": 2.3522
}
```

**Output:**
```
๐Ÿ“… 5-Day Forecast

๐Ÿ“ Coordinates : 48.8566, 2.3522
๐ŸŒ Timezone    : Europe/Paris

๐Ÿ“… 2024-03-29
   ๐ŸŒก๏ธ  18ยฐC โ€“ 24ยฐC (feels 16ยฐC โ€“ 26ยฐC)
   โ˜๏ธ  Partly cloudy
   ๐Ÿ’ง Precipitation: 0.2 mm (0 rain + 0.1 showers + 0 snow)
   ๐ŸŒง๏ธ Chance: 15% over 0.5h
   ๐ŸŒ… Sunrise: 06:45 | Sunset: 19:32
   โ˜€๏ธ  Sunshine: 8.2h / Daylight: 12.8h
   โ˜€๏ธ  UV Index: 6 (Clear sky: 7)
   ๐Ÿ’จ Wind: 15 km/h gusts to 22 km/h from W
   โšก Solar Radiation: 18.5 MJ/mยฒ
   ๐ŸŒฑ Reference ETโ‚€: 4.2 mm
```

#### `get_server_stats`
Get server performance metrics and cache statistics.

**Input:** (no parameters required)

**Output:**
```
๐Ÿ“Š Server Statistics

โฑ๏ธ  Uptime: 45 minutes
๐Ÿ”„ API Calls: 127
๐Ÿ’พ Cache Hits: 89 (70.1%)
โŒ Errors: 2
โšก Avg Response Time: 245ms

๐Ÿ”ง Tool Usage:
   โ€ข get_weather: 95 calls
   โ€ข get_weather_forecast: 32 calls

๐Ÿ“‹ Cache Status:
   โ€ข Connected: โœ…
   โ€ข Keys: 23
   โ€ข Memory: 2.4MB
```

## ๐Ÿงช Testing

### Run Test Suite
```bash
# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Run in watch mode
npm run test:watch
```

### Test Architecture
- **64 unit tests** covering all services and server components
- **Mocked API calls** for reliable testing without network dependencies
- **Cache testing** with Redis mock
- **Schema validation** testing with Zod
- **Error handling** coverage

### Test Files
```
tests/
โ”œโ”€โ”€ services/
โ”‚   โ”œโ”€โ”€ weatherApi.test.js     # API client tests
โ”‚   โ””โ”€โ”€ weatherCodes.test.js   # Weather code mapping tests
โ””โ”€โ”€ server/
    โ””โ”€โ”€ weatherMcpFactory.test.js # Server factory tests
```

## ๐Ÿ“ˆ Monitoring & Metrics

### Built-in Metrics
- **API Call Tracking**: Count, response times, cache hit rates
- **Tool Usage**: Per-tool invocation counts
- **Error Tracking**: Error types and frequencies
- **Cache Performance**: Hit rates, memory usage, connection status
- **Server Health**: Uptime, active sessions

### Logs
Structured logging with:
- Request/response timing
- Cache operations
- API call details
- Error context
- Performance metrics

### Cache Configuration
```javascript
// Current weather: 15 minutes TTL
// Forecasts: 1 hour TTL
// Automatic expiration and cleanup
```

## ๐Ÿ”’ Security & Reliability

### Data Validation
- **Zod schemas** for all inputs
- **Coordinate bounds** checking (-90/+90, -180/+180)
- **API response** validation
- **Error sanitization** (no sensitive data leakage)

### Error Handling
- **Graceful degradation** (continues without cache)
- **Structured error responses** with appropriate HTTP codes
- **Timeout handling** for API calls
- **Connection retry** logic for Redis

### Performance
- **Connection pooling** for Redis
- **Request deduplication** via caching
- **Memory-efficient** data structures
- **Background cleanup** of expired cache entries

## ๐Ÿค Contributing

### Development Setup
```bash
# Install dependencies
npm install

# Run tests
npm test

# Start development server
npm run dev

# Debug mode
npm run debug
```

### Code Quality
- **ESLint** configuration for code style
- **Prettier** for consistent formatting
- **Jest** for comprehensive testing
- **TypeScript definitions** for better IDE support

### Architecture Guidelines
- **Layer separation**: Services, Tools, Server layers
- **Dependency injection**: Injectable fetch/cache for testing
- **Error boundaries**: Comprehensive error handling
- **Logging standards**: Structured logging throughout

## ๐Ÿ“„ License

**MIT License** - Free for personal and commercial use.

### Open-Meteo Terms
- Non-commercial use: Unlimited API calls
- Commercial use: Contact Open-Meteo for licensing
- Attribution required for public deployments

## ๐Ÿ™ Acknowledgments

- **Open-Meteo** for providing free, high-quality weather data
- **Anthropic** for the Model Context Protocol specification
- **Weather model providers**: ECMWF, NOAA, Mรฉtรฉo-France, DWD, and others

## ๐Ÿ“ž Support

### Issues & Bugs
- GitHub Issues: Report bugs and request features
- Documentation: Check this README first

### Community
- **MCP Discord**: Join the Model Context Protocol community
- **Open-Meteo Forum**: Weather API discussions

---

**Built with โค๏ธ using the Model Context Protocol**

### Stdio Mode (Default)
```bash
npm start
# or: node src/index.js
```
Perfect for direct MCP client integration (Claude Desktop, IDEs, etc.)

### HTTP/SSE Mode
```bash
# Via CLI flag
npm run start:http
# or: node src/index.js --http

# Via environment variables
TRANSPORT=http PORT=8080 node src/index.js

# Default HTTP port: 3001
```

**HTTP Endpoints:**
- `GET /health` - Health check endpoint
- `GET /sse` - Server-Sent Events stream
- `POST /messages` - Tool request endpoint

### Demo Script
```bash
node demo.js
```
Shows real-world example calls to weather service for multiple cities.

### Run Tests
```bash
npm test
```
Validates input schemas and weather code mappings.

## ๐Ÿ› ๏ธ Available Tools

### Tool: `get_weather`
Get current weather for a location.

**Parameters:**
```json
{
  "latitude": -90 to 90,
  "longitude": -180 to 180
}
```

**Example:**
```bash
# Request current weather for Paris
{
  "latitude": 48.8566,
  "longitude": 2.3522
}
```

**Response Example:**
```
โ˜€๏ธ **CURRENT WEATHER**

๐Ÿ“ Location: 48.8566ยฐN, 2.3522ยฐE
๐ŸŒก๏ธ  Temperature: 15ยฐC
โ˜๏ธ  Condition: Partly cloudy
๐Ÿ’ง Humidity: 65%
๐Ÿ’จ Wind Speed: 12 km/h
๐Ÿ• Time: 2024-03-29T10:30:00Z
๐ŸŒ Timezone: Europe/Paris
```

### Tool: `get_forecast`
Get 5-day weather forecast.

**Parameters:**
```json
{
  "latitude": -90 to 90,
  "longitude": -180 to 180
}
```

**Response Example:**
```
๐Ÿ“… **5-DAY WEATHER FORECAST**

๐Ÿ“ Location: 48.8566ยฐN, 2.3522ยฐE
๐ŸŒ Timezone: Europe/Paris

**Day 1** - 2024-03-29
โ˜๏ธ Partly cloudy
๐Ÿ”บ Max: 18ยฐC | ๐Ÿ”ป Min: 12ยฐC

**Day 2** - 2024-03-30
๐ŸŒง๏ธ Slight rain
๐Ÿ”บ Max: 16ยฐC | ๐Ÿ”ป Min: 10ยฐC

...
```

## ๐ŸŒ Popular Coordinates

| City | Latitude | Longitude |
|------|----------|-----------|
| Paris | 48.8566 | 2.3522 |
| London | 51.5074 | -0.1278 |
| New York | 40.7128 | -74.0060 |
| Tokyo | 35.6762 | 139.6503 |
| Sydney | -33.8688 | 151.2093 |
| Berlin | 52.5200 | 13.4050 |
| Los Angeles | 34.0522 | -118.2437 |

## ๐Ÿ”— Data Source

- **API**: [Open-Meteo](https://open-meteo.com/) - Free, open-source weather API
- **Documentation**: https://open-meteo.com/en/docs
- **Weather Codes**: [WMO Weather Interpretation Codes](https://www.noaa.gov/media/e1906d56-9acc-4ea6-a60c-4e214a01b47f/WMO-Weather-interpretation-codes.pdf)

## ๐Ÿ“ฆ Module System

Uses **ES Modules (ESM)** with `"type": "module"` for modern JavaScript features:
- Clean import/export syntax
- Top-level await support
- Better tree-shaking compatibility

## ๐Ÿงช Testing

```bash
npm test
```

**Test Coverage:**
- Input coordinate validation (bounds checking)
- Weather code mapping (WMO codes)
- Schema validation with Zod
- Edge cases and error handling

## ๐Ÿ“ Project Structure

```
MCP-Weather/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ index.js           # Main entry point
โ”‚   โ”œโ”€โ”€ server.js          # MCP server factory
โ”‚   โ”œโ”€โ”€ weatherService.js  # Weather API service
โ”‚   โ””โ”€โ”€ weatherTools.js    # MCP tools
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ demo.js                # Demo script
โ”œโ”€โ”€ test.js                # Test suite
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ .env.example
```

## ๐Ÿ”ง Environment Variables

| Variable | Values | Default | Purpose |
|----------|--------|---------|---------|
| `TRANSPORT` | `stdio`, `http` | `stdio` | Transport mode |
| `PORT` | `1-65535` | `3001` | HTTP server port (HTTP mode only) |

**Example:**
```bash
# Run in HTTP mode on custom port
TRANSPORT=http PORT=8080 npm start
```

## ๐Ÿ› Troubleshooting

| Issue | Solution |
|-------|----------|
| `MODULE_NOT_FOUND` | Ensure `"type": "module"` in package.json |
| Port 3001 in use | Set custom port: `PORT=3002 npm run start:http` |
| Invalid coordinates error | Check bounds: latitude [-90, 90], longitude [-180, 180] |
| "Unknown weather condition" | WMO code mapping - check Open-Meteo documentation |
| ESM import errors | Verify all imports have `.js` file extension |

## ๐Ÿ“œ License

ISC

## ๐Ÿค Contributing

This project follows the MCP specification and best practices for Node.js server development.