🌤️ MCP Сервер Погоды с Deepseek
Простой MCP сервер для получения погоды через OpenWeatherMap API с использованием Deepseek API в качестве интерфейса и поддержкой модульной архитектуры.
📋 Что это делает?
- 🌍 Получает текущую погоду для любого города через OpenWeatherMap API
- 📅 Показывает прогноз погоды на несколько дней
- 🤖 Использует Deepseek для естественного общения и вызова инструментов с реальными данными
- 📦 Интегрирован с удалённой PostgreSQL базой и FastAPI для работы с данными о начислениях
- 🔧 Реализует протокол MCP для подключения AI к внешним данным
- 🏗️ Модульная архитектура с асинхронными операциями
📁 Структура проекта
OpenWeatherMap_MCP/
├── modules/ # Пакет модулей приложения
│ ├── __init__.py # Инициализация пакета модулей
│ ├── config.py # Конфигурация (загрузка переменных окружения)
│ ├── weather_api.py # Функции для работы с OpenWeatherMap API
│ ├── deepseek_api.py # Функции для работы с Deepseek API
│ └── file_api.py # Функции для файловых операций
├── fastapi_udalennii/ # Удалённый FastAPI проект (на другом хосте)
│ ├── app/
│ │ ├── main.py # FastAPI приложение с endpoints
│ │ ├── models.py # SQLAlchemy таблицы (users, accruals)
│ │ ├── schemas.py # Pydantic схемы для валидации
│ │ ├── crud.py # CRUD операции для БД
│ │ ├── db.py # Подключение к БД
│ │ └── config.py # Конфигурация
│ ├── alembic/ # Миграции БД
│ │ └── versions/
│ │ ├── 0001_create_users_table.py
│ │ └── 0002_create_accruals_table.py
│ ├── requirements.txt # Зависимости FastAPI
│ ├── .env # Конфиг БД для удалённого сервера
│ └── README.md # Инструкции для удалённого FastAPI
├── deepseek_client.py # Клиент для интерактивного чата с Deepseek
├── server.py # MCP сервер с инструментами погоды
├── test_project.py # Тесты
├── .env # API ключи (не добавляйте в Git!)
├── requirements.txt # Python зависимости для локального клиента
├── DEPLOYMENT_INSTRUCTIONS.md # Инструкции по развёртыванию FastAPI
└── README.md # Эта инструкция
🚀 Быстрый старт
1. Установка зависимостей
# Создайте виртуальное окружение
python3 -m venv venv
# Активируйте его
# На macOS/Linux:
source venv/bin/activate
# На Windows:
venv\Scripts\activate
# Установите зависимости
pip3 install -r requirements.txt
2. Настройка API ключей и подключений
Создайте файл .env в корне проекта:
# ===== OpenWeatherMap =====
OPENWEATHER_API_KEY=ваш_ключ_здесь
OPENWEATHER_BASE_URL=https://api.openweathermap.org/data/2.5
# ===== Deepseek =====
DEEPSEEK_API_KEY=ваш_ключ_здесь
# ===== Database (PostgreSQL) =====
DATABASE_URL=postgresql://username:password@192.168.0.134:5432/mydb
# ===== Accruals API (Remote FastAPI) =====
ACCRUALS_API_URL=http://192.168.0.137:8000
# ===== File Operations =====
ALLOWED_BASE_DIR=/path/to/allowed/dir
# ===== Logging =====
LOG_LEVEL=INFO
Получение API ключей:
-
OpenWeatherMap:
- Зарегистрируйтесь на https://openweathermap.org
- Перейдите в раздел API Keys
- Скопируйте ключ (бесплатный план: 1000 запросов/день)
-
Deepseek:
- Зарегистрируйтесь на https://platform.deepseek.com
- Создайте новый API ключ
- Пополните баланс (бесплатный кредит ~$5)
3. Запуск Deepseek клиента
python3 deepseek_client.py
4. (Опционально) Работа через удалённый API для начислений
Deepseek может запрашивать данные о начислениях через REST API (FastAPI) — если у вас уже развернут удалённый API, укажите его базовый URL в переменной ACCRUALS_API_URL.
ACCRUALS_API_URL=http://192.168.0.137:8000
Убедитесь, что удалённая база и API содержат необходимые данные — локальные утилиты для загрузки Excel (modules/db_loader.py) удалены из репозитория. После настройки ACCRUALS_API_URL Deepseek сможет запрашивать статистику и списки начислений у удалённого сервера.
Теперь в клиенте Deepseek можно спрашивать о начислениях (см. примеры ниже).
💬 Примеры использования
Работа с погодой
После запуска deepseek_client.py просто спрашивайте о погоде на естественном языке:
👤 Вы: Какая погода в Москве?
🤖 Deepseek: [Проверяет текущую погоду в Москве через API и показывает результат]
👤 Вы: А какой прогноз на 5 дней для Санкт-Петербурга?
🤖 Deepseek: [Показывает прогноз на 5 дней]
👤 Вы: Что лучше надеть в Лондоне сегодня?
🤖 Deepseek: [Проверяет погоду и дает рекомендации]
👤 Вы: выход
👋 До свидания!
Работа с данными о начислениях (Ozon)
После запуска API (см. раздел "Запуск API для работы с БД") можно запрашивать данные:
👤 Вы: Покажи статистику по начислениям
🤖 Deepseek: [Запрашивает /stats/summary и показывает общую сводку: кол-во записей, платформы, типы]
👤 Вы: Сколько начислений по услугам доставки?
🤖 Deepseek: [Запрашивает /stats/accruals?service_group=Услуги+доставки и показывает статистику]
👤 Вы: Покажи список последних начислений с платформы Ozon
🤖 Deepseek: [Запрашивает /accruals?sales_platform=Ozon&limit=50 и показывает записи]
👤 Вы: выход
👋 До свидания!
🔧 Описание модулей
modules/config.py
Отвечает за: конфигурацию приложения, загрузку переменных окружения, валидацию ключей API.
Основные компоненты:
Config- класс с константами конфигурацииvalidate()- проверяет наличие критических переменных окруженияget_config_summary()- возвращает сводку конфигурации для логирования
modules/weather_api.py
Отвечает за: взаимодействие с OpenWeatherMap API для получения данных о погоде.
Основные функции:
make_weather_request()- вспомогательная функция для HTTP запросов к APIget_current_weather()- получает текущую погоду для городаget_forecast()- получает прогноз на несколько днейformat_day_forecast()- форматирует прогноз на один день
modules/deepseek_api.py
Отвечает за: взаимодействие с Deepseek API для обработки запросов пользователя с использованием инструментов (функций).
Основные функции:
get_weather_tools()- возвращает определение инструментов для Deepseekcall_deepseek_with_tools()- вызывает Deepseek с поддержкой инструментов (function calling)process_deepseek_response()- обрабатывает ответ от Deepseek, выполняет вызовы инструментовget_weather_response()- главная функция для получения ответа о погоде
Поддерживаемые инструменты:
- Погода:
get_current_weather,get_forecast - Файлы:
read_file,create_file,update_file,append_to_file,delete_file,list_files
modules/file_api.py
Отвечает за: безопасную работу с файлами по определённому пути.
Основные функции:
read_file()- чтение содержимого файлаcreate_file()- создание нового файлаupdate_file()- обновление содержимого файлаappend_to_file()- добавление содержимого в файлdelete_file()- удаление файлаlist_files()- просмотр содержимого директорииis_path_safe()- проверка безопасности пути (предотвращает path traversal атаки)
Примеры команд для Deepseek:
- "Создай файл test.txt с текстом 'Hello World'"
- "Прочитай содержимое файла README.md"
- "Обнови файл config.py на новый код"
- "Покажи список файлов в папке modules"
- "Добавь новую строку в файл notes.txt"
- "Удали временный файл temp.txt"
server.py
Отвечает за: запуск MCP сервера с инструментами для интеграции с другими приложениями.
Основные инструменты MCP:
current_weather()- инструмент для получения текущей погодыweather_forecast()- инструмент для получения прогноза
Для запуска только MCP сервера (для интеграции с другими приложениями):
uv run mcp dev server.py
Удалённые локальные модули
Ранее в репозитории были утилиты для локальной загрузки данных и локальный API:
modules/db.py— локальная SQLAlchemy модель и хелперы для создания таблицmodules/db_loader.py— скрипт загрузки Excel (pandas → БД)modules/api.py— FastAPI приложение для доступа к данным о начислениях
Эти файлы удалены из текущего репозитория в пользу использования удалённых сервисов (базы данных и API). Если вам нужно восстановить локальную загрузку или локальный API, можно восстановить соответствующие модули и добавить в requirements.txt зависимости: pandas, openpyxl, sqlalchemy, psycopg2-binary, uvicorn.
deepseek_client.py
Отвечает за: главную точку входа приложения - интерактивный чат с пользователем.
Основные функции:
chat_with_deepseek()- интерактивный цикл чата с естественным языкомmain()- инициализация и запуск приложения
Для запуска полного приложения:
python3 deepseek_client.py
Это команда, которая вам нужна! Она запускает интерактивный чат с Deepseek, который использует реальные данные о погоде из OpenWeatherMap API и может запрашивать данные о начислениях (если API запущен).
🌐 Схема взаимодействия
Пользователь
↓
deepseek_client.py (chat_with_deepseek)
↓
modules/deepseek_api.py (get_weather_response)
↓
Deepseek API
├─ Анализирует запрос
└─ Вызывает инструменты (function calling)
↓
modules/weather_api.py
├─ get_current_weather()
└─ get_forecast()
↓
OpenWeatherMap API
↓
Возвращает реальные данные о погоде
↓
Deepseek API (обработка результатов инструментов)
↓
Финальный ответ пользователю
🔌 Добавление новых функций
Чтобы добавить новый инструмент (например, получение качества воздуха):
- Добавьте функцию в модуль
modules/weather_api.py:
async def get_air_quality(city: str) -> str:
"""Получить качество воздуха для города"""
# Реализация...
return result
- Добавьте определение инструмента в
modules/deepseek_api.py:
def get_weather_tools() -> List[Dict[str, Any]]:
tools = [
# ... существующие инструменты ...
{
"type": "function",
"function": {
"name": "get_air_quality",
"description": "Получить качество воздуха",
# ... параметры ...
}
}
]
return tools
- Добавьте обработку в
process_deepseek_response():
if tool_name == "get_air_quality":
result = await get_air_quality(tool_args.get("city"))
- Добавьте инструмент в MCP сервер
server.py:
@mcp.tool()
async def air_quality(city: str) -> str:
"""Инструмент MCP для получения качества воздуха"""
return await get_air_quality(city)
📊 Логирование
Приложение использует встроенный модуль logging для отслеживания всех операций. Логи записываются в файл app.log и выводятся в консоль.
Уровни логирования:
DEBUG- подробная информация для отладкиINFO- основная информация о работеWARNING- предупрежденияERROR- ошибкиCRITICAL- критические ошибки
Уровень логирования можно настроить через переменную окружения LOG_LEVEL в .env.
🧪 Тестирование только сервера
Если хотите протестировать MCP сервер без клиента:
# Используйте MCP Inspector
uv run mcp dev server.py
# Или установите в Claude Desktop
uv run mcp install server.py --name "Weather Service"
🐛 Поиск и решение проблем
Ошибка: "OPENWEATHER_API_KEY не найден"
Решение: Убедитесь, что файл .env находится в корне проекта и содержит OPENWEATHER_API_KEY=ваш_ключ
Ошибка: "Не удалось получить погоду для города"
Решение:
- Проверьте написание названия города
- Убедитесь, что у вас есть интернет подключение
- Проверьте, не исчерпан ли лимит бесплатного плана OpenWeatherMap
Ошибка: "Ошибка при обращении к Deepseek API"
Решение:
- Проверьте, что DEEPSEEK_API_KEY скопирован правильно
- Убедитесь, что на вашем счёте есть баланс для API запросов
- Проверьте статус Deepseek API на https://status.deepseek.com/
📝 Лицензия
Этот проект лицензирован под MIT License.
🤝 Контрибьютинг
Приветствуются pull requests! Для больших изменений сначала откройте issue для обсуждения.
🛠️ Доступные инструменты
get_current_weather
Получает текущую погоду для города
Параметры:
city(обязательный): Название городаunits(опционально): "metric" или "imperial"
get_forecast
Получает прогноз погоды на несколько дней
Параметры:
city(обязательный): Название городаdays(опционально): Количество дней (1-5)units(опционально): "metric" или "imperial"
🌐 Архитектура с удалённым FastAPI
Проект использует двухуровневую архитектуру:
Локальный слой (ваша машина)
- deepseek_client.py - интерактивный чат с Deepseek
- modules/deepseek_api.py - интеграция с Deepseek для обработки запросов
- modules/weather_api.py - получение данных о погоде
- modules/file_api.py - файловые операции
Удалённый слой (другой хост 192.168.0.137:8000)
- fastapi_udalennii/app/main.py - REST API для работы с начислениями (accruals)
- fastapi_udalennii/app/models.py - SQLAlchemy таблицы (users, accruals)
- fastapi_udalennii/app/crud.py - операции БД
- fastapi_udalennii/app/schemas.py - валидация данных (Pydantic)
База данных (PostgreSQL)
- Хост: 192.168.0.134:5432
- База: mydb
- Пользователь: asx
Схема взаимодействия:
Пользователь
↓
deepseek_client.py
↓
Deepseek API (обработка запроса)
├─ Погода → modules/weather_api.py → OpenWeatherMap API
├─ Файлы → modules/file_api.py → локальная ФС
└─ Начисления → httpx HTTP запрос → fastapi_udalennii (192.168.0.137:8000)
├─ GET /accruals/ → fastapi_udalennii/app/crud.py → PostgreSQL
├─ GET /stats/summary → fastapi_udalennii/app/crud.py → PostgreSQL
└─ POST /accruals/ → fastapi_udalennii/app/crud.py → PostgreSQL
↓
Deepseek API (формирует ответ)
↓
Пользователю
Новые endpoints в FastAPI:
После развёртывания на удалённом сервере (см. DEPLOYMENT_INSTRUCTIONS.md) доступны:
Accruals endpoints:
POST /accruals/- создание новой записи о начисленииGET /accruals/- получение списка с фильтрацией
Stats endpoints:
GET /stats/summary- общая статистика по всем начислениямGET /stats/accruals- статистика с фильтрацией
Примеры запросов:
# Получить все начисления
curl http://192.168.0.137:8000/accruals/
# Получить начисления по платформе Ozon
curl "http://192.168.0.137:8000/accruals/?sales_platform=Ozon&limit=50"
# Получить статистику
curl http://192.168.0.137:8000/stats/summary
# Создать новое начисление
curl -X POST http://192.168.0.137:8000/accruals/ \
-H "Content-Type: application/json" \
-d '{
"id_accrual": "ACC001",
"accrual_date": "2025-12-08",
"service_group": "Доставка",
"accrual_type": "Комиссия",
"sales_platform": "Ozon",
"total_amount_rub": 1234.56
}'
⚙️ Развёртывание и обновления
Для развёртывания обновлённого FastAPI на удалённом сервере смотрите инструкции в DEPLOYMENT_INSTRUCTIONS.md.
Краткая схема:
- Синхронизация кода через
rsync - Активация venv на удалённом сервере
- Установка зависимостей (если добавлены новые)
- Запуск миграций Alembic
- Перезагрузка FastAPI сервиса
⚠️ Важные замечания
- Не используйте
print()в server.py - это сломает STDIO транспорт - Храните
.envв безопасности - добавьте в.gitignore - Лимиты API:
- OpenWeatherMap Free: 1000 запросов/день
- Deepseek: зависит от вашего плана
- Стоимость Deepseek: Более дешевая чем OpenAI
- Миграции БД: После обновления FastAPI кода обязательно запустите
alembic upgrade head
🐛 Решение проблем
Ошибка: "OPENWEATHER_API_KEY не найден"
- Проверьте, что файл
.envсоздан и содержит ключ - Убедитесь, что файл находится в той же папке, что и скрипты
Ошибка: "Не удалось получить погоду"
- Проверьте правильность написания города
- Попробуйте английское название города
Сервер не запускается
- Убедитесь, что виртуальное окружение активировано
- Проверьте, что все зависимости установлены
