# Weather Service API

A comprehensive weather service library that provides easy access to current weather conditions and forecasts using the OpenWeatherMap API.

## Features

- 🌤️ Get current weather data for any city
- 📅 Get multi-day forecasts (up to 5 days)
- 🔄 Built-in retry logic with exponential backoff
- 🛡️ Proper error handling
- 📊 Well-structured data formatting
- 📝 Human-readable weather descriptions
- 🔌 TypeScript support with full type definitions
- 🚀 MCP (Model Context Protocol) server integration
- 🧰 CLI tool for easy access via npx

## Project Structure

The project follows a modular architecture for better maintainability:

```
src/
  ├── api/             # API client implementation
  ├── cli/             # CLI implementation
  ├── config/          # Configuration management
  ├── formatters/      # Data formatting utilities
  ├── server/          # MCP server implementation
  ├── types/           # TypeScript interfaces and types
  ├── utils/           # Helper utilities 
  ├── cli.ts           # CLI entry point
  └── index.ts         # Main entry point
```

## Installation

```bash
npm install weather-service-api
```

You'll need to set up an OpenWeatherMap API key. You can sign up for a free key at [OpenWeatherMap](https://openweathermap.org/api).

## CLI Usage with npx

You can use the weather service directly from the command line with npx without installing it globally:

### Start the MCP Server

```bash
npx -y weather-service-api server start
```

Or with an API key provided directly:

```bash
npx -y weather-service-api server start -k YOUR_API_KEY
```

### Get Current Weather

```bash
npx -y weather-service-api weather "New York" -k YOUR_API_KEY
```

With custom options:

```bash
npx -y weather-service-api weather London -u imperial -l es -k YOUR_API_KEY
```

### Get Weather Forecast

```bash
npx -y weather-service-api forecast Paris -d 5 -k YOUR_API_KEY
```

## Basic Usage (as a library)

### Environment Setup

Create a `.env` file in your project root:

```
WEATHER_API_KEY=your_openweathermap_api_key_here
```

### Getting Current Weather

```javascript
import { WeatherApiClient } from 'weather-service-api';

// Create a new weather service instance
const weatherClient = new WeatherApiClient();

// Get current weather
async function showWeather() {
  try {
    // Get structured weather data
    const weatherData = await weatherClient.getCurrentWeather('New York');
    console.log(`Temperature: ${weatherData.temperature.current}°C`);
    console.log(`Conditions: ${weatherData.weather.description}`);
    
    // Or use the formatter for a nicely formatted output
    import { formatCurrentWeather } from 'weather-service-api';
    const formattedWeather = formatCurrentWeather(weatherData);
    console.log(formattedWeather);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

showWeather();
```

### Getting Weather Forecast

```javascript
import { WeatherApiClient, formatForecast } from 'weather-service-api';

const weatherClient = new WeatherApiClient();

async function showForecast() {
  try {
    // Get a 3-day forecast
    const forecastData = await weatherClient.getForecast('London', 3);
    
    // Access structured forecast data
    forecastData.forecasts.forEach(day => {
      console.log(`${day.date.toLocaleDateString()}: ${day.temperature.avg.toFixed(1)}°C, ${day.weather.description}`);
    });
    
    // Or get formatted human-readable forecast
    const formattedForecast = formatForecast(forecastData);
    console.log(formattedForecast);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

showForecast();
```

### Using with Custom Options

```javascript
import { WeatherApiClient } from 'weather-service-api';

// Configure with custom options
const weatherClient = new WeatherApiClient({
  apiKey: 'your_api_key_here', // Use this instead of .env
  units: 'imperial', // Use Fahrenheit instead of Celsius
  language: 'es', // Get weather descriptions in Spanish
  maxRetries: 5 // Increase retry attempts
});

async function getWeather() {
  const weather = await weatherClient.getCurrentWeather('Paris');
  console.log(`Temperature: ${weather.temperature.current}°F`);
}

getWeather();
```

## Advanced Usage: MCP Server

This package also includes a ready-to-use MCP (Model Context Protocol) server implementation that you can use to expose weather data to AI assistants.

### Using the library:

```javascript
import { startServer } from 'weather-service-api';

// Start the MCP server
startServer();
```

### Using VS Code settings.json:

Add this to your VS Code settings.json to make it available as an MCP agent:

```json
"mcp": {
  "servers": {
    "Weather MCP Server": {
      "command": "npx",
      "args": [
        "-y",
        "rui-weather-service-api",
        "server",
        "start"
      ],
      "env": {
        "WEATHER_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

## API Reference

### WeatherApiClient Class

```typescript
constructor(options?: {
  apiKey?: string,
  baseUrl?: string,
  units?: 'metric' | 'imperial',
  language?: string,
  maxRetries?: number,
  timeout?: number,
  rejectUnauthorized?: boolean
})
```

#### Methods

- `getCurrentWeather(city: string): Promise<WeatherData>`
- `getForecast(city: string, days?: number): Promise<ForecastData>`

### Configuration Functions

- `updateConfig(options: ConfigOptions): void`
- `getConfig(): ConfigOptions`
- `validateConfig(): void`

### Formatting Functions

- `formatCurrentWeather(weatherData: WeatherData): string`
- `formatForecast(forecastData: ForecastData): string`
- `formatTemperature(temperature: number): string`
- `formatWindSpeed(speed: number): string`

### CLI Commands

- `server start`: Start the MCP server
- `weather <city>`: Get current weather for a city
- `forecast <city>`: Get weather forecast for a city

## License

ISC

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.