🌤️ MCP Weather Server + Next.js Chat
Полноценное решение для получения погоды через AI-ассистента. Включает MCP сервер на TypeScript и веб-интерфейс чата на Next.js.
🔗 MCP Tool Chain (NEW!)
Проект поддерживает композицию из трёх MCP-инструментов с автоматической агентной цепочкой:
┌────────────────────────────────────────────────────────────────────────────┐
│ MCP TOOL CHAIN │
├────────────────────────────────────────────────────────────────────────────┤
│ │
│ User: "Какая погода в Риге и что мне надеть?" │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Claude AI (Orchestrator) │ │
│ │ Автоматически определяет цепочку инструментов │ │
│ └───────────────────────────┬─────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼─────────────────────────────────────────┐ │
│ │ ▼ │ │
│ │ 1️⃣ get_weather ──► 2️⃣ analyze_weather ──► 3️⃣ save_weather_report │ │
│ │ (Яндекс API) (Рекомендации) (Файл отчёта) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Response: "В Риге -2°C. Рекомендую зимнюю куртку. [Скачать отчёт]" │
│ │
└────────────────────────────────────────────────────────────────────────────┘
Три MCP инструмента
| Инструмент | Описание | Входные параметры | Выход | |------------|----------|-------------------|-------| | get_weather | Получение погоды из Яндекс API | city | температура, условия, влажность, давление | | analyze_weather | Анализ и рекомендации | weather_data, analysis_type | рекомендации по одежде/активностям/здоровью | | save_weather_report | Сохранение отчёта | city, weather_data, analysis, format | путь к файлу, URL для скачивания |
Типы анализа
- clothing — что надеть (куртка, шапка, зонт и т.д.)
- activity — подходящие активности (пробежка, велосипед, пикник)
- health — влияние на здоровье (давление, влажность, риски)
Форматы отчётов
- md — Markdown с таблицами и эмодзи
- txt — простой текстовый файл
- json — структурированные данные
📐 Архитектура
┌─────────────────────────────────────────────────────────────────────────────┐
│ АРХИТЕКТУРА │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ВАРИАНТ A: Claude Desktop + MCP (stdio) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐│
│ │ Claude Desktop │────▶│ MCP Server │────▶│ Яндекс Weather API ││
│ │ │◀────│ (stdio) │◀────│ ││
│ └─────────────────┘ └─────────────────┘ └─────────────────────────┘│
│ │
│ ВАРИАНТ B: Web Interface + MCP Tool Chain │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐│
│ │ Browser │────▶│ Next.js │────▶│ Claude API ││
│ │ │◀────│ (tool_use) │◀────│ (Orchestrator) ││
│ └─────────────────┘ └────────┬────────┘ └─────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────┐ ┌─────────────────────────┐│
│ │ MCP Server │────▶│ Яндекс Weather API ││
│ │ (HTTP :3001) │◀────│ + File System ││
│ │ 3 MCP Tools │ │ ││
│ └─────────────────┘ └─────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Claude автоматически выбирает инструменты на основе запроса пользователя!
📁 Структура проекта
mcp-server/
├── src/ # MCP Server (TypeScript)
│ ├── server.ts # MCP сервер (stdio для Claude Desktop)
│ ├── server-http.ts # MCP сервер (HTTP) с 3 инструментами
│ ├── weather-service.ts # Сервис работы с Yandex API
│ ├── tools/ # MCP инструменты
│ │ ├── weather-analyzer.ts # Анализ погоды (clothing/activity/health)
│ │ └── report-saver.ts # Сохранение отчётов (txt/json/md)
│ ├── cities.ts # База координат городов
│ ├── cache.ts # In-memory кэширование
│ ├── logger.ts # Логгер
│ └── types.ts # TypeScript типы
├── weather-chat/ # Next.js приложение
│ ├── app/ # App Router
│ │ ├── api/chat/ # API чата с Claude (tool_use)
│ │ ├── api/weather/ # API погоды
│ │ ├── api/analyze/ # API анализа
│ │ ├── api/save-report/ # API сохранения отчётов
│ │ ├── api/tool-chain/ # API полной цепочки
│ │ ├── tools/page.tsx # Страница Tool Chain UI
│ │ └── page.tsx # Главная страница
│ ├── components/
│ │ ├── Chat.tsx # Компонент чата
│ │ └── WeatherToolChain.tsx # Визуализация цепочки
│ ├── lib/mcp-client.ts # Клиент для MCP HTTP сервера
│ ├── types/weather.ts # TypeScript типы
│ └── public/reports/ # Директория для отчётов
├── nginx/ # Nginx конфигурация
├── scripts/ # Скрипты развёртывания
├── ecosystem.config.cjs # PM2 конфигурация
└── claude_desktop_config.json # Конфиг для Claude Desktop
🚀 Быстрый старт
1. Установка MCP сервера
# Установка зависимостей
npm install
# Сборка TypeScript
npm run build
# Создание .env.local файла
cp .env.local.example .env.local
# Отредактируйте .env.local и добавьте YANDEX_WEATHER_API_KEY
2. Установка Next.js приложения
cd weather-chat
# Установка зависимостей
npm install
# Создание .env.local.local
cat > .env.local.local << EOF
YANDEX_WEATHER_API_KEY=ваш-ключ-яндекс
ANTHROPIC_API_KEY=ваш-ключ-anthropic
EOF
# Запуск в режиме разработки
npm run dev
3. Получение API ключей
Яндекс Weather API
- Перейдите на https://developer.tech.yandex.ru/
- Создайте приложение
- Включите API "Яндекс Погода"
- Скопируйте ключ
Anthropic API
- Перейдите на https://console.anthropic.com/
- Создайте API ключ
- Скопируйте ключ
🔧 Варианты подключения
Вариант A: Claude Desktop + MCP Server
Для локального использования с Claude Desktop:
- Соберите MCP сервер:
npm run build
- Найдите конфигурацию Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- Добавьте конфигурацию:
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/полный/путь/к/mcp-server/dist/server.js"],
"env": {
"YANDEX_WEATHER_API_KEY": "ваш-api-ключ",
"LOG_LEVEL": "info",
"CACHE_TTL": "300"
}
}
}
}
- Перезапустите Claude Desktop
- Теперь можно спрашивать: "Какая погода в Риге?"
Вариант B: Next.js Web Interface
Для веб-интерфейса с чатом (через MCP HTTP сервер):
- Настройте переменные окружения в
weather-chat/.env.local:
YANDEX_WEATHER_API_KEY=ваш-ключ
ANTHROPIC_API_KEY=ваш-ключ
MCP_SERVER_URL=http://127.0.0.1:3001
- Запустите MCP HTTP сервер:
# В корне проекта
npm run build
npm run start:http
# или для разработки: npm run dev:http
- Запустите Next.js (в другом терминале):
cd weather-chat
npm run dev
- Откройте http://localhost:3000
Важно: MCP HTTP сервер должен быть запущен на порту 3001!
🖥️ Развёртывание на VPS
Требования
- Ubuntu 20.04+ / Debian 11+
- Node.js 18+
- Nginx
- PM2
Шаги развёртывания
- Подготовка сервера:
# Обновление системы
sudo apt update && sudo apt upgrade -y
# Установка Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Установка PM2
sudo npm install -g pm2
# Установка Nginx
sudo apt install -y nginx
- Клонирование и настройка:
# Клонируем проект
git clone https://github.com/your-repo/mcp-server.git /var/www/mcp-server
cd /var/www/mcp-server
# Настраиваем права
sudo chown -R $USER:$USER /var/www/mcp-server
- Настройка переменных окружения:
# MCP Server
cat > .env.local << EOF
YANDEX_WEATHER_API_KEY=ваш-ключ
LOG_LEVEL=info
CACHE_TTL=300
EOF
# Next.js
cat > weather-chat/.env.local.local << EOF
YANDEX_WEATHER_API_KEY=ваш-ключ
ANTHROPIC_API_KEY=ваш-ключ
EOF
- Запуск через скрипт:
chmod +x scripts/deploy.sh
./scripts/deploy.sh deploy
- Настройка Nginx:
# Копируем конфигурацию
sudo cp nginx/weather-chat.conf /etc/nginx/sites-available/weather-chat
# Редактируем домен
sudo nano /etc/nginx/sites-available/weather-chat
# Активируем
sudo ln -s /etc/nginx/sites-available/weather-chat /etc/nginx/sites-enabled/
# Проверяем и перезапускаем
sudo nginx -t
sudo systemctl reload nginx
- SSL сертификат (Let's Encrypt):
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d weather.yourdomain.com
PM2 команды
# Статус
pm2 status
# Логи
pm2 logs weather-chat
# Перезапуск
pm2 restart weather-chat
# Остановка
pm2 stop weather-chat
# Мониторинг
pm2 monit
🧪 Тестирование
Тестирование MCP сервера
# Сборка
npm run build
# Тест через echo (stdin)
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | YANDEX_WEATHER_API_KEY=ваш-ключ node dist/server.js
Тестирование API погоды
# GET запрос
curl "http://localhost:3000/api/weather?city=Рига"
# POST запрос
curl -X POST http://localhost:3000/api/weather \
-H "Content-Type: application/json" \
-d '{"city": "Москва"}'
Тестирование чата
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Какая сейчас погода в Риге?"}'
Тестирование MCP Tool Chain (curl)
# 1. Получить погоду (MCP Server)
curl -X POST http://localhost:3001/api/weather \
-H "Content-Type: application/json" \
-d '{"city": "Рига"}'
# 2. Анализ погоды (с результатом шага 1)
curl -X POST http://localhost:3001/api/analyze \
-H "Content-Type: application/json" \
-d '{
"weather_data": {
"temperature": -2,
"condition": "облачно",
"humidity": 87,
"pressure": 760,
"city": "Рига",
"feels_like": -6,
"wind_speed": 4
},
"analysis_type": "clothing"
}'
# 3. Сохранить отчёт
curl -X POST http://localhost:3001/api/save-report \
-H "Content-Type: application/json" \
-d '{
"city": "Рига",
"weather_data": {"temperature": -2, "condition": "облачно", "humidity": 87, "pressure": 760, "city": "Рига"},
"analysis": {"type": "clothing", "city": "Рига", "temperature": -2, "condition": "облачно", "summary": "Тест", "timestamp": "2024-12-18T12:00:00Z"},
"format": "md"
}'
# 4. Выполнить всю цепочку (Next.js)
curl -X POST http://localhost:3000/api/tool-chain \
-H "Content-Type: application/json" \
-d '{"city": "Рига", "analysis_type": "clothing", "format": "md"}'
Ожидаемый ответ погоды
{
"success": true,
"data": {
"temperature": -2,
"condition": "облачно с прояснениями",
"humidity": 87,
"pressure": 760,
"city": "Рига",
"feels_like": -6,
"wind_speed": 4
}
}
Ожидаемый ответ анализа
{
"success": true,
"data": {
"type": "clothing",
"city": "Рига",
"temperature": -2,
"condition": "облачно с прояснениями",
"summary": "В Рига сейчас -2°C, облачно с прояснениями. ❄️ Морозно. Нужна тёплая зимняя одежда",
"clothing": {
"main": "❄️ Морозно. Нужна тёплая зимняя одежда",
"items": ["Зимняя куртка", "Тёплый свитер", "Джинсы/тёплые штаны", "Шапка", "Шарф", "Перчатки", "Зимняя обувь"]
},
"timestamp": "2024-12-18T12:00:00.000Z"
}
}
Ожидаемый ответ сохранения отчёта
{
"success": true,
"data": {
"file_path": "/reports/weather_riga_2024-12-18_14-30.md",
"file_url": "/reports/weather_riga_2024-12-18_14-30.md",
"file_name": "weather_riga_2024-12-18_14-30.md",
"file_size": 1234,
"format": "md",
"timestamp": "2024-12-18T12:30:00.000Z"
}
}
💬 Примеры диалогов с агентом
Пример 1: Что надеть
User: Какая погода в Риге и что мне надеть?
Claude вызывает:
1. get_weather({city: "Рига"})
→ {temperature: -5, condition: "снег", feels_like: -10, ...}
2. analyze_weather({weather_data: {...}, analysis_type: "clothing"})
→ {main: "❄️ Морозно. Нужна тёплая зимняя одежда", items: [...]}
Response:
🌨️ В Риге сейчас -5°C, идёт снег. Ощущается как -10°C.
👔 Рекомендую надеть:
• Зимняя куртка или пуховик
• Тёплый свитер
• Шапка и перчатки обязательно!
• Зимняя обувь
❄️ На улице снег - выбирайте непромокаемую обувь.
Пример 2: Пробежка
User: Можно ли сегодня бегать в Москве?
Claude вызывает:
1. get_weather({city: "Москва"})
→ {temperature: 5, condition: "ясно", wind_speed: 3, ...}
2. analyze_weather({weather_data: {...}, analysis_type: "activity"})
→ {suitable: ["🏃 Пробежка"], tips: [...]}
Response:
☀️ В Москве 5°C, ясно. Отличные условия для пробежки!
🏃 Рекомендации:
• Идеальная температура для бега
• Ветер слабый (3 м/с) — не помешает
• Возьмите ветровку на всякий случай
Пример 3: Полная цепочка с отчётом
User: Сделай отчёт о погоде в Париже для здоровья
Claude вызывает:
1. get_weather({city: "Париж"})
→ {temperature: 12, pressure: 745, humidity: 75, ...}
2. analyze_weather({weather_data: {...}, analysis_type: "health"})
→ {risk_level: "medium", warnings: ["📉 Низкое давление"], ...}
3. save_weather_report({city: "Париж", ..., format: "md"})
→ {file_url: "/reports/weather_parizh_2024-12-18.md", ...}
Response:
🌤️ В Париже 12°C.
❤️ Влияние на здоровье:
🟡 Уровень риска: средний
⚠️ Предупреждения:
• 📉 Низкое атмосферное давление (745 мм) — возможны головные боли
💡 Рекомендации:
• Избегайте физических нагрузок
• Пейте больше воды
📄 [Скачать полный отчёт](/reports/weather_parizh_2024-12-18.md)
🔒 Безопасность
- ✅ API ключи только на сервере (не передаются клиенту)
- ✅ Rate limiting через Nginx
- ✅ HTTPS обязателен в продакшене
- ✅ Валидация входных данных через Zod
- ✅ Логирование без секретов
- ✅ Автоматическая оркестрация инструментов через Claude
📊 Структурированный ответ погоды
interface WeatherResponse {
temperature: number; // °C
condition: string; // "ясно", "дождь", etc.
humidity: number; // %
pressure: number; // мм рт.ст.
city: string; // Название города
feels_like?: number; // Ощущаемая температура
wind_speed?: number; // м/с
icon?: string; // Код иконки
}
📄 Пример сгенерированного отчёта (Markdown)
# 🌤️ Отчёт о погоде: Рига
> Сгенерировано: 18.12.2024, 14:30:00
---
## 📊 Текущая погода
| Параметр | Значение |
|----------|----------|
| 🌡️ Температура | **-2°C** |
| 🤒 Ощущается как | -6°C |
| ☁️ Условия | облачно с прояснениями |
| 💧 Влажность | 87% |
| 📊 Давление | 760 мм рт.ст. |
| 💨 Ветер | 4 м/с |
---
## 👔 Рекомендации по одежде
**В Рига сейчас -2°C, облачно с прояснениями. ❄️ Морозно. Нужна тёплая зимняя одежда**
### 📋 Что надеть
- Зимняя куртка
- Тёплый свитер
- Джинсы/тёплые штаны
- Шапка
- Шарф
- Перчатки
- Зимняя обувь
---
*Источник данных: Яндекс Weather API*
*Сгенерировано MCP Weather Server*
🌍 Поддерживаемые города
- Россия: Москва, Санкт-Петербург, Казань, Сочи, Владивосток, +20 городов
- Прибалтика: Рига, Таллин, Вильнюс
- СНГ: Минск, Киев, Алматы, Астана
- Европа: Берлин, Париж, Лондон, Амстердам, +15 городов
- Азия: Токио, Пекин, Сингапур, Дубай
- Америка: Нью-Йорк, Лос-Анджелес, Торонто
📝 Лицензия
ISC
🤝 Контрибуция
Pull requests приветствуются! Для крупных изменений сначала откройте issue.






