Skip to main content
Glama
README.md
# Weather MCP 🌤️

一個 **Model Context Protocol (MCP)** 天氣查詢應用專案,提供天氣數據檢索、LangChain Agent 整合和資料視覺化功能。

## 🚀 功能特色

### 核心功能
- **MCP 伺服器**: 基於 FastMCP 的 stdio 協定天氣工具伺服器
- **MCP 客戶端**: 支援異步操作和錯誤處理的客戶端工具
- **LangChain 整合**: React Agent 模式,支援自然語言天氣查詢
- **資料視覺化**: 使用 matplotlib 的天氣趨勢圖表
- **多語言支援**: 中英文天氣查詢和回應

### 天氣工具
- 🌍 **地理編碼**: 城市名稱轉經緯度 (Open-Meteo Geocoding API)
- 🌡️ **天氣預報**: 1-24小時逐時天氣預報 (Open-Meteo Forecast API)
- 📅 **多日預報**: 支援 1-16 天天氣預報,可指定日期查詢
- 🕒 **歷史天氣**: 支援查詢過去 92 天的天氣數據
- 🤖 **智能日期**: 自動判斷過去/未來,只需提供日期
- 🗣️ **自然語言**: Agent 自動理解「昨天」「明天」「3天前」等時間表達
- ⚠️ **天氣警報**: 天氣警報查詢 (示意功能)
- 📊 **資料視覺化**: 溫度、濕度、降水機率和風速圖表

## 📦 專案結構

```
weather_mcp/
├── src/weather_mcp/          # 主程式套件
│   ├── __init__.py          # 套件初始化
│   ├── server.py            # MCP 伺服器
│   ├── client.py            # MCP 客戶端
│   ├── tools.py             # LangChain 工具包裝
│   ├── agent.py             # LangChain Agent 整合
│   └── visualization.py     # 視覺化工具
├── examples/                # 使用範例
│   └── simple_usage.py      # 基本使用範例
├── tests/                   # 測試檔案
├── docs/                    # 文件
├── main.py                  # 主執行程式
├── requirements.txt         # 依賴套件
├── pyproject.toml          # 專案配置
└── README.md               # 說明文件
```

## 🛠️ 安裝與設定

### 1. 複製專案
```bash
git clone <repository-url>
cd weather_mcp
```

### 2. 建立虛擬環境
```bash
python -m venv venv
source venv/bin/activate  # Linux/Mac
# 或
venv\\Scripts\\activate  # Windows
```

### 3. 安裝依賴
```bash
pip install -r requirements.txt
```

### 4. 設定環境變數 (Agent 功能需要)
```bash
cp .env.example .env
# 編輯 .env 檔案,設定您的 GOOGLE_API_KEY
nano .env  # 或使用任何文字編輯器
```

**注意**: 程式會自動讀取 `.env` 檔案(需要 `python-dotenv` 套件,已包含在 requirements.txt 中)

## 🏃‍♂️ 快速開始

### 快速測試
```bash
# 執行快速測試腳本(驗證所有功能)
python test_quick.py
```

### 基本使用
```python
from weather_mcp import WeatherMCPClient

# 建立客戶端
client = WeatherMCPClient()

# 查詢城市天氣
result = client.get_city_weather("Tokyo", hours=12)
print(result)
```

### LangChain Agent 模式
```python
import os
from weather_mcp import WeatherAgent

# 設定 API Key
os.environ["GOOGLE_API_KEY"] = "your_api_key"

# 建立 Agent
agent = WeatherAgent()

# 自然語言查詢(支援時間理解)
answer = agent.ask_weather("昨天東京天氣如何?")  # 歷史天氣
print(answer)

answer = agent.ask_weather("明天台北會下雨嗎?")  # 未來天氣
print(answer)

answer = agent.ask_weather("3天前倫敦的天氣")  # 歷史天氣
print(answer)
```

### 資料視覺化
```python
from weather_mcp import WeatherMCPClient, create_visualizer
from weather_mcp.visualization import plot_weather_trends_horizontal

client = WeatherMCPClient()
result = client.get_city_weather("Tokyo", hours=12)

# 方法1: 快速繪圖
plot_weather_trends_horizontal(result["weather"], "Tokyo Weather")

# 方法2: 使用視覺化物件
visualizer = create_visualizer()
fig = visualizer.plot_all_metrics(result["weather"], "Tokyo")
fig.savefig("tokyo_weather.png")
```

## 🎯 主程式使用

### 互動模式
```bash
python main.py --mode interactive
```

互動模式支援以下命令:
- `viz [city] [date]` - 天氣視覺化(日期為可選的 YYYY-MM-DD 格式)
- `raw [city] [date]` - 顯示原始天氣數據(日期為可選的 YYYY-MM-DD 格式)
- 自然語言查詢(需要 API Key)

範例:
```bash
viz Tokyo                 # 今天東京天氣視覺化
viz Tokyo 2025-10-01      # 昨天東京天氣視覺化
raw London 2025-10-03     # 明天倫敦原始數據
```

### 執行範例
```bash
# 客戶端範例
python main.py --mode client

# Agent 範例 (需要 API Key)
python main.py --mode agent --api-key your_key

# 視覺化範例(今天)
python main.py --mode viz

# 視覺化範例(指定日期)
python main.py --mode viz --city Tokyo --date 2025-10-01

# MCP 伺服器
python main.py --mode server
```

### 使用範例程式
```bash
python examples/simple_usage.py
python examples/test_date_feature.py    # 測試日期功能
```

## 🔧 API 參考

### WeatherMCPClient

```python
class WeatherMCPClient:
    def geocode_city(self, city: str) -> Dict[str, Any]
    def get_weather(self, lat: float, lon: float, hours: int = 12) -> Dict[str, Any]
    def get_alerts(self, lat: float, lon: float) -> Dict[str, Any]
    def get_city_weather(self, city: str, hours: int = 12) -> Dict[str, Any]
```

### WeatherAgent

```python
class WeatherAgent:
    def ask_weather(self, question: str, language: str = "zh-tw") -> str
    def get_weather_data(self, city: str, hours: int = 12) -> Dict[str, Any]
    def translate_city_name(self, city: str) -> str
```

### WeatherVisualizer

```python
class WeatherVisualizer:
    def plot_temperature_trend(self, weather_data: Dict[str, Any]) -> plt.Figure
    def plot_weather_overview(self, weather_data: Dict[str, Any]) -> plt.Figure
    def plot_all_metrics(self, weather_data: Dict[str, Any]) -> plt.Figure
    def get_weather_summary(self, weather_data: Dict[str, Any]) -> Dict[str, Any]
```

## 🌐 支援的城市

內建中英文城市名稱對照:
- 日本/東京 → Tokyo
- 台灣/台北 → Taipei
- 中國/北京 → Beijing
- 韓國/首爾 → Seoul
- 美國/華盛頓 → Washington
- 英國/倫敦 → London
- 法國/巴黎 → Paris
- 德國/柏林 → Berlin
- 印度/新德里 → New Delhi

## 📊 資料來源

- **地理編碼**: [Open-Meteo Geocoding API](https://open-meteo.com/en/docs/geocoding-api)
- **天氣預報**: [Open-Meteo Forecast API](https://open-meteo.com/en/docs)
- **AI 模型**: Google Gemini 2.5 Flash (透過 LangChain)

## 🧪 測試

```bash
# 安裝測試依賴
pip install -e ".[dev]"

# 執行測試
pytest

# 執行測試並顯示覆蓋率
pytest --cov=weather_mcp
```

## 🤝 貢獻

1. Fork 專案
2. 建立功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交變更 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 開啟 Pull Request

## 📝 License

本專案採用 MIT License - 詳見 [LICENSE](LICENSE) 檔案。

## 🔍 故障排除

### 常見問題

1. **MCP 伺服器啟動失敗**
   - 確認已安裝所有依賴套件
   - 檢查 `mcp_server.log` 錯誤訊息

2. **Agent 功能無法使用**
   - 確認已設定 `GOOGLE_API_KEY` 環境變數
   - 檢查 API Key 是否有效

3. **視覺化圖表無法顯示**
   - 確認已安裝 matplotlib
   - 在 Jupyter 環境中使用 `%matplotlib inline`

4. **網路連線錯誤**
   - 檢查網路連線
   - 確認防火牆設定允許存取 Open-Meteo API

### Debug 模式

```bash
# 啟用詳細日誌
export DEBUG=true
python main.py --mode interactive
```

## 📚 進階功能

### 歷史與未來天氣查詢

支援查詢過去 92 天和未來 16 天的天氣,系統自動判斷:

```python
from datetime import datetime, timedelta
from weather_mcp import WeatherMCPClient

client = WeatherMCPClient()

# 查詢昨天的天氣(自動設定 past_days)
yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
result = client.get_city_weather(city="Tokyo", target_date=yesterday)

# 查詢明天的天氣(自動設定 forecast_days)
tomorrow = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
result = client.get_city_weather(city="Paris", target_date=tomorrow)

# 不提供 target_date,自動使用今天
result = client.get_city_weather(city="London")
```

**自然語言查詢**:Agent 自動理解時間表達

```python
agent = WeatherAgent()

# 歷史天氣
agent.ask_weather("昨天東京天氣如何?")
agent.ask_weather("3天前台北的天氣")

# 未來天氣
agent.ask_weather("明天倫敦會下雨嗎?")
agent.ask_weather("後天巴黎的天氣")
```

詳細說明請參考:
- [docs/DATE_FEATURE.md](docs/DATE_FEATURE.md) - viz/raw 日期功能說明
- [docs/HISTORICAL_WEATHER.md](docs/HISTORICAL_WEATHER.md) - 歷史天氣查詢
- [docs/MULTI_DAY_FORECAST.md](docs/MULTI_DAY_FORECAST.md) - 多日預報功能

## 📞 支援與聯絡

- 問題回報: [GitHub Issues](https://github.com/weather-mcp/weather-mcp/issues)
- 文件: [專案 Wiki](https://github.com/weather-mcp/weather-mcp/wiki)
- 範例: `examples/` 目錄

## 📖 更多文檔

- [HISTORICAL_WEATHER.md](docs/HISTORICAL_WEATHER.md) - 歷史天氣查詢功能
- [MULTI_DAY_FORECAST.md](docs/MULTI_DAY_FORECAST.md) - 多日預報功能說明
- [LOGGING.md](docs/LOGGING.md) - 日誌系統說明
- [SERVER_STARTUP.md](docs/SERVER_STARTUP.md) - 伺服器啟動機制
- [DYNAMIC_HOURS.md](docs/DYNAMIC_HOURS.md) - 動態時間功能
- [ENV_SETUP.md](docs/ENV_SETUP.md) - 環境變數設定

---

**Weather MCP** - 讓天氣查詢變得簡單而強大! 🌈