Skip to main content
Glama
TSchwierz

weather-packing-bot

by TSchwierz

weather-packing-bot

Бот, работающий по расписанию, который публикует в Slack сообщение с многодневным прогнозом погоды и рекомендациями по сбору вещей для регулярного маршрута между тремя городами. Он также представляет собой небольшую эталонную реализацию пары MCP-сервера и MCP-клиента (Model Context Protocol): данные прогноза предоставляются отдельным MCP-сервером и потребляются MCP-клиентом, а не запрашиваются напрямую скриптом бота.

Обзор

Бот запускается по еженедельному расписанию (по пятницам, 15:00 CEST) и публикует в Slack сообщение о погоде на период с этого дня до вечера следующего понедельника. Прогноз и рекомендации по сбору вещей учитывают маршрут: они определяют, в каком из трёх городов ожидается путешественник в каждый день этого окна, а не показывают погоду во всех городах без разбора.

GitHub Actions (scheduled, Fridays)
        │
        ▼
bot/packing_advisor.py            MCP client
        │  spawns as subprocess, communicates over stdio
        ▼
mcp_server/weather_server.py      MCP server, queries Open-Meteo
        │
        ▼
   Slack incoming webhook

Зачем нужны MCP-сервер и MCP-клиент

Сервер предоставляет инструменты для работы с погодой, не зная, кто их вызывает и зачем, — это может быть данный бот, ассистент в IDE или любой другой MCP-совместимый клиент. Клиент не импортирует Python-функции сервера напрямую: он обнаруживает доступные инструменты во время выполнения (session.list_tools()) и вызывает их по имени через протокол (session.call_tool(...)). Именно это разделение отличает данную архитектуру от простого вызова функции в том же процессе.

Компоненты

mcp_server/weather_server.py

MCP-сервер (использующий класс MCPServer из пакета mcp), который оборачивает API Open-Meteo и предоставляет четыре инструмента:

Tool

Description

list_cities()

Возвращает названия настроенных городов.

get_forecast(city, days=3)

Ежедневная сводка погоды для одного города.

get_forecast_all(days=3)

Ежедневная сводка погоды для каждого настроенного города.

render_temperature_chart(days=4)

Компактная текстовая диаграмма по городам и дням (температурная полоса, значок погоды, осадки), отформатированная для кодового блока Slack.

Города определяются в словаре COORDINATES и могут свободно расширяться.

bot/packing_advisor.py

MCP-клиент, который:

  1. Вычисляет окно прогноза — от текущей даты до следующего понедельника включительно — с помощью forecast_window().

  2. Запускает weather_server.py в качестве подпроцесса, выполняет рукопожатие MCP и вызывает get_forecast_all и render_temperature_chart для этого окна.

  3. Сопоставляет каждую дату в окне со словарём WEEKLY_ITINERARY, который ставит в соответствие дню недели город (или города), где ожидается путешественник в этот день, чтобы на результат влияли только релевантные города.

  4. Передаёт сопоставленные дни в recommend_packing() — функцию на основе правил, использующую пороговые значения температуры и осадков (без внешнего вызова ИИ).

  5. Формирует сообщение в формате Slack Block Kit — разбивку по дням, список вещей и диаграмму — и публикует его через входящий вебхук.

Маршрут поездок

WEEKLY_ITINERARY в bot/packing_advisor.py описывает повторяющийся еженедельный маршрут:

WEEKLY_ITINERARY = {
    4: [("Nijmegen", "arrival")],       # Friday
    5: [("Nijmegen", "")],              # Saturday
    6: [("Nijmegen", "")],              # Sunday
    0: [("Den Bosch", "day"), ("Kerpen", "evening, back home")],  # Monday
}

В понедельник две записи, потому что это переходный день: маршрут помещает путешественника днём в Ден-Бос, а к вечеру — обратно в Керпен. Этот словарь — единственное место, которое нужно изменить, если маршрут изменится.

Диаграмма

render_temperature_chart создаёт текстовую моноширинную диаграмму, а не изображение. Это намеренное ограничение: входящий вебхук Slack может отправлять только текст или JSON Block Kit — он не может загружать бинарные файлы. Публикация реального изображения потребовала бы токена Slack-бота (установленного Slack-приложения с областью files:write) и вызова files.upload через Web API Slack вместо вебхука. Это возможное расширение, но оно требует управления дополнительными учётными данными; текущая реализация полностью избегает этого требования.

Настройка

Предварительные требования

  • Приложение Slack с URL входящего вебхука.

  • Репозиторий GitHub для размещения кода и запуска запланированного рабочего процесса.

Локальный запуск

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # fill in SLACK_WEBHOOK_URL
export $(grep -v '^#' .env | xargs)
python bot/packing_advisor.py

SIMULATE_DATE (см. .env.example) можно задать в виде ISO-даты, чтобы проверить логику маршрута и окна прогноза, не дожидаясь реальной пятницы.

MCP-сервер также можно изучить отдельно:

pip install "mcp[cli]"
mcp dev mcp_server/weather_server.py

Это открывает MCP Inspector в браузере; это удобно для просмотра схем инструментов и прямого вызова таких инструментов, как get_forecast или render_temperature_chart.

Конфигурация репозитория GitHub

  • Добавьте SLACK_WEBHOOK_URL в качестве секрета репозитория (Настройки → Секреты и переменные → Actions → Секреты).

  • Никакой другой конфигурации репозитория не требуется: маршрут определён в коде, а не в виде переменной репозитория.

Расписание

.github/workflows/weekly-forecast.yml запускается каждую пятницу в 13:00 UTC (15:00 CEST) по расписанию cron: "0 13 * * 5". Расписания cron в GitHub Actions не учитывают переход на летнее время, поэтому в период CET (зимой) запуск происходит в 14:00 по местному времени вместо 15:00; выражение cron можно корректировать по сезонам, если это смещение важно. Рабочий процесс также поддерживает ручной запуск (workflow_dispatch) с необязательным входным параметром simulate_date; это удобно для тестирования, прежде чем полагаться на расписание.

Известные ограничения и возможные расширения

  • Сообщение Slack включает текстовую диаграмму, а не изображение, по причине, описанной выше. PNG-диаграмма через matplotlib в сочетании с токеном Slack-бота и files.upload — возможный следующий шаг.

  • recommend_packing() основан на правилах. Замена этой функции вызовом LLM (например, Anthropic API) позволила бы получать более естественный текстовый вывод; результаты инструментов MCP — это обычные словари, поэтому их можно напрямую передавать в такой вызов.

  • Маршрут — это фиксированный еженедельный шаблон. Источник с интеграцией календаря (например, чтение фактических дат поездок из календаря) позволил бы выйти за рамки повторяющегося еженедельного маршрута.

Примечания об исходном материале

В исходном черновом скрипте сервера было несколько проблем, исправленных при разработке данной реализации:

  • Неиспользуемый и несуществующий импорт httpx2.

  • get_params() формировал словарь параметров, но не возвращал его.

  • Клиент Open-Meteo создавался только внутри if __name__ == "__main__", из-за чего он был недоступен функциям-инструментам, которые ссылались на него на уровне модуля.

  • process_response пытался выполнить присваивание в list, используя объект dict_keys в качестве индекса, что недопустимо.

  • Функции-инструменты возвращали объекты pandas DataFrame и скалярные типы numpy, которые не сериализуются в JSON; результаты инструментов MCP должны быть сериализуемыми, поскольку они передаются в виде JSON.

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Open-Meteo MCP — weather forecast + historical reanalysis + sister APIs

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • OpenWeather MCP — wraps the OpenWeatherMap API (openweathermap.org)

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TSchwierz/AutomationsAndMCPs'

If you have feedback or need assistance with the MCP directory API, please join our Discord server