Skip to main content
Glama
HumairaShaista

weather-learning-server

Изучение Weather MCP

Прогрессивный учебный проект, показывающий путь от простого LLM-приложения до возможностей работы с погодой, предоставляемых через Model Context Protocol (MCP).

Этапы обучения

  1. Простое LLM-приложение — чат с локальной open-source моделью через Ollama

  2. Традиционное приложение с погодным API — клиент Open-Meteo (Этап 2A) + прямая оркестрация LLM (Этап 2B)

  3. Weather MCP сервер — предоставление погоды как MCP-инструментов через stdio (Этап 3)

  4. MCP клиент / агент — явный клиент инструментов (Этап 4A) + инструменты, выбираемые моделью (Этап 4B)

В этом репозитории реализованы этапы с 1 по 4B.

Related MCP server: MCP Weather Server Demo

Требования

  • Python 3.12 или новее

  • Ollama (или любой локальный сервер, совместимый с OpenAI)

  • Локальная open-source модель с поддержкой вызова инструментов (по умолчанию: qwen2.5:7b)

Учётная запись OpenAI или Gemini не требуется.

Настройка

1. Установка и запуск Ollama

Установите с https://ollama.com, затем загрузите модель:

ollama pull qwen2.5:7b

Или используйте любую другую модель с возможностью вызова инструментов, которая у вас уже есть (ollama list), затем укажите LLM_MODEL в .env с её именем.

Убедитесь, что Ollama запущен (обычно это происходит автоматически на macOS после установки):

ollama list

2. Создание виртуального окружения

python3 -m venv .venv
source .venv/bin/activate

На Windows:

python -m venv .venv
.venv\Scripts\activate

3. Установка зависимостей

pip install -e ".[dev]"

4. Настройка переменных окружения

cp .env.example .env

Значения по умолчанию в .env указывают на локальный Ollama:

LLM_BASE_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
LLM_MODEL=qwen2.5:7b
  • LLM_BASE_URL — URL API, совместимого с OpenAI (по умолчанию указан Ollama; используется для Chat Completions и Responses)

  • LLM_API_KEY — требуется клиентской библиотекой; Ollama игнорирует его (подойдёт любое непустое значение)

  • LLM_MODEL — имя локальной модели из ollama list (на Этапе 4B вызов инструментов хорошо работает с qwen2.5:7b)

Другие варианты: LM Studio, vLLM или любой сервер, поддерживающий chat-API OpenAI — просто измените LLM_BASE_URL и LLM_MODEL.

Этап 2A: Клиент погоды Open-Meteo

app/weather_client.py работает с Open-Meteo в два шага (без LLM, без MCP):

  1. ГеокодированиеGET https://geocoding-api.open-meteo.com/v1/search преобразует название города (и необязательно штат/регион и страну) в широту, долготу, каноническое название, административный регион, страну и часовой пояс.

  2. ПрогнозGET https://api.open-meteo.com/v1/forecast использует эти координаты для получения текущей погоды (температура, влажность, ветер, WMO-код погоды).

Вызывающие получают типизированные модели (Location, CurrentWeather, WeatherResult), а не сырые JSON от провайдера. Преобразование WMO-кода погоды в текст находится в одном месте (WMO_WEATHER_CODES / weather_condition_from_code).

Пример (асинхронный):

from app.weather_client import get_current_weather

result = await get_current_weather("Berlin")
print(result.location.name, result.current.temperature, result.current.condition)

Этап 2B: Приложение с прямым вызовом погоды и LLM

app/direct_weather_app.py — это традиционное LLM-приложение: ваш код решает, когда вызывать погодный API, затем передаёт результат LLM для дружественного резюме.

User
  → direct_weather_app
      → Open-Meteo   (application-controlled)
      → LLM          (summarize only the supplied payload)
  → Response

Как запустить

При активированном виртуальном окружении, запущенном Ollama и наличии сетевого доступа к Open-Meteo:

python -m app.direct_weather_app "San Francisco"

Необязательное уточнение:

python -m app.direct_weather_app "Springfield" --state Illinois --country US

Или через консольный скрипт:

direct-weather "San Francisco"

В stderr вы увидите шаги оркестрации:

  1. Приложение получило город

  2. Приложение вызвало погодного провайдера

  3. Приложение получило структурированные данные о погоде

  4. Приложение отправило контекст погоды в LLM

Stdout показывает структурированный блок погоды, затем резюме LLM.

Чем отличается от простого LLM-приложения

Этап 1 plain_llm_app

Этап 2B direct_weather_app

Данные о погоде

Нет — у модели нет актуальной погоды

Сначала получены из Open-Meteo

Кто вызывает погоду?

Никто

Код приложения (явно)

Роль LLM

Ответ на произвольный запрос

Обобщение авторитетных данных

MCP / инструменты

Нет

Нет

Важный учебный момент: LLM не находит и не вызывает погодные инструменты. Приложение само оркестрирует Open-Meteo, затем просит LLM сформулировать результат. Подсказка сообщает модели, что данные авторитетны и не нужно выдумывать недостающие факты.

Этап 3: Weather MCP сервер

app/mcp_server.py предоставляет существующий weather_client как MCP инструмент. Сервер предоставляет только возможности — он не общается с LLM и не управляет диалогом.

Официальная версия SDK и используемый API

Проверено в окружении этого проекта:

Пункт

Значение

Пакет

официальный mcp на PyPI (modelcontextprotocol/python-sdk)

Установленная версия

2.0.0

Класс сервера

MCPServer из mcp.server

Не используется

сторонний пакет fastmcp; старый путь импорта v1 FastMCP

from mcp.server import MCPServer

mcp = MCPServer("weather-learning-server")

Обязанности сервера

  • Предоставлять инструменты MCP-клиентам (обнаружение инструментов)

  • Принимать вызов инструмента get_current_weather

  • Делегировать выполнение app.weather_client (без дублирования кода Open-Meteo)

  • Возвращать структурированные данные о погоде (или безопасную ошибку инструмента)

  • Общаться по MCP через stdio для локального прототипа

Контракт предоставляемого инструмента: get_current_weather

Аргументы

Имя

Тип

Обязательный

Описание

city

string

да

Название города или места

state_or_region

string

нет

Штат / административный регион для уточнения

country

string

нет

Название страны или код ISO-3166-1 alpha-2

Поля структурированного результата

resolved_location, region, country, latitude, longitude, temperature, apparent_temperature (если доступно), condition, wind_speed, observation_time, timezone, units

Как запустить сервер

python -m app.mcp_server

Или:

weather-mcp-server

При stdio процесс ожидает MCP-хоста на stdin/stdout. Если запустить его в одиночку в терминале, он будет выглядеть «зависшим» — это нормально.

Как работает stdio-транспорт (концептуально)

MCP host / Inspector
   ├── spawns: python -m app.mcp_server
   ├── writes JSON-RPC MCP messages → server stdin
   └── reads JSON-RPC MCP messages  ← server stdout
  • Для этого прототипа нет порта и HTTP

  • stdout является проводом протокола (не используйте print() для обычного вывода приложения)

  • Логи должны идти в stderr

Независимое тестирование с официальным MCP Inspector

Проверено с:

  • официальным mcp 2.0.0 (MCPServer)

  • официальным пакетом Inspector @modelcontextprotocol/inspector

  • Node.js 22.19+ (требуется текущей документацией Inspector)

  • сетевым доступом к Open-Meteo

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

cd weather-mcp-learning
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"   # includes mcp[cli]

Проверьте Node/npx:

node --version   # need 22.19.0 or newer
npx --version

Если ваша системная node/npx сломана или слишком старая, используйте актуальную Node через nvm (или аналог), затем убедитесь, что npx находится первым в PATH.

Вариант A — Веб-интерфейс через mcp dev (официальный помощник SDK)

Из корня проекта с активным venv (также требуется uv, потому что mcp dev запускает сервер через uv run):

mcp dev app/mcp_server.py --with-editable .

Ожидается:

  1. Терминал выведет что-то вроде MCP Inspector Web is up and running at: http://localhost:6274?MCP_INSPECTOR_API_TOKEN=...

  2. Браузер откроет Inspector

  3. Inspector запустится/подключится к локальному stdio-серверу (weather-learning-server)

  4. Сессия инициализируется (появятся имя сервера/инструкции)

  5. Откройте Tools → список покажет get_current_weather

  6. Выберите инструмент → UI покажет docstring/описание и поля ввода из схемы (city обязательно; state_or_region / country опционально)

  7. Установите city = San FranciscoRun Tool

  8. Панель результатов покажет структурированный контент, например resolved_location, region, temperature, condition, units и т.д.

--with-editable . устанавливает этот проект во временное окружение, которое создаёт mcp dev, чтобы работало import app....

Вариант B — Веб-интерфейс через Inspector + конфигурация проекта

mcp-inspector.json в корне репозитория указывает Inspector на локальный stdio-сервер:

npx -y @modelcontextprotocol/inspector --config ./mcp-inspector.json --server weather-learning-server

Откройте выведенный URL http://localhost:6274?..., подтвердите подключение сессии, затем используйте вкладку Tools как в Варианте A.

Вариант C — Скриптовые проверки через CLI (без браузера)

Они полезны, чтобы проверить те же протокольные шаги из терминала. Запускайте из корня проекта с активным venv и работающим Node 22.19+ npx в PATH:

# 1–2. Start/connect over stdio + initialize session
npx -y @modelcontextprotocol/inspector --cli \
  --config ./mcp-inspector.json \
  --server weather-learning-server \
  --method initialize \
  --format json

Ожидается JSON с "name": "weather-learning-server" в result.serverInfo.

# 3–4. List tools; confirm description + input schema
npx -y @modelcontextprotocol/inspector --cli \
  --config ./mcp-inspector.json \
  --server weather-learning-server \
  --method tools/list \
  --format json

Ожидается: один инструмент с именем get_current_weather, с inputSchema.required, содержащим city, и описание текущей погоды.

# 5–6. Invoke with city = San Francisco; display structured result
npx -y @modelcontextprotocol/inspector --cli \
  --config ./mcp-inspector.json \
  --server weather-learning-server \
  --method tools/call \
  --tool-name get_current_weather \
  --tool-arg 'city=San Francisco' \
  --format json

Ожидается: "isError": false и structuredContent с полями, такими как:

{
  "resolved_location": "San Francisco",
  "region": "California",
  "country": "United States",
  "latitude": 37.77493,
  "longitude": -122.41942,
  "temperature": 13.8,
  "apparent_temperature": 12.1,
  "condition": "Fog",
  "wind_speed": 19.1,
  "observation_time": "2026-08-12T22:45",
  "timezone": "America/Los_Angeles",
  "units": {
    "temperature": "°C",
    "wind_speed": "km/h",
    "apparent_temperature": "°C"
  }
}

Числовые значения погоды меняются со временем; важны имена полей и "isError": false.

Официальная документация Inspector: MCP Inspector · Документация SDK по запуску: Running your server

Этап 4A: Базовый MCP клиент (явный вызов инструмента)

app/basic_mcp_client.py — это не-LLM MCP клиент. Он запускает локальный погодный MCP сервер через stdio, обнаруживает инструменты, затем явно вызывает get_current_weather.

basic_mcp_client
    → list_tools
    → get_current_weather   (hardcoded by this app — not chosen by an LLM)
    → MCP server (app.mcp_server via stdio)
    → Open-Meteo

Важно: этот клиент по-прежнему вызывает погодный инструмент явно. LLM ещё не выбирал инструмент. Это будет на более позднем этапе.

Как запустить

При активированном виртуальном окружении (не нужно запускать MCP сервер вручную — этот клиент запускает его сам):

python -m app.basic_mcp_client "San Francisco"

Необязательные фильтры:

python -m app.basic_mcp_client "Springfield" --state Illinois --country US

Или:

basic-mcp-client "San Francisco"

Вы должны увидеть:

  1. Информацию о подключении / протоколе для weather-learning-server

  2. Каждый обнаруженный инструмент: имя, описание и входную схему

  3. Явный вызов get_current_weather

  4. Структурированный JSON результат MCP инструмента

Завершение процесса очищает MCP сессию и дочерний процесс сервера.

Этап 4B: Агент OpenAI Responses (инструменты MCP, выбираемые моделью)

app/mcp_agent.py подключается к погодному MCP серверу, обнаруживает инструменты во время выполнения, передаёт эти определения модели через официальный OpenAI Responses API, выполняет любые запрошенные моделью вызовы инструментов через MCP, возвращает результаты инструментов модели и выводит итоговый ответ.

user question
  → mcp_agent
      → MCP list_tools          (discovery)
      → OpenAI Responses API    (question + tool schemas)
      → model may request tool(s)
      → MCP tools/call          (only discovered names)
      → Responses function_call_output
      → final natural-language answer

Нет if "weather" in question, нет регулярного выражения для города и нет жёстко закодированного вызова get_current_weather. Модель решает, использовать ли инструмент.

Цикл агента (подробно)

  1. Запуск MCP сессии — запустить python -m app.mcp_server через stdio; инициализировать клиент

  2. Обнаружение инструментовlist_tools; залогировать имя/описание каждого инструмента

  3. Преобразование схем — MCP инструменты → инструменты типа "function" для Responses

  4. Ход моделиclient.responses.create(..., tools=..., tool_choice="auto")

  5. Проверка вывода — если присутствуют function_call:

    • проверить имя инструмента среди обнаруженного набора

    • разобрать/проверить JSON аргументы

    • вызвать MCP; сохранить структурированные результаты

    • отправить function_call_output с previous_response_id

  6. Повторять, пока модель не вернёт финальное текстовое сообщение (или не достигнут максимум итераций)

  7. Вывести итоговый ответ и закрыть MCP сессию/дочерний процесс

Как запустить

ollama pull qwen2.5:7b   # once, if needed
source .venv/bin/activate
python -m app.mcp_agent "What is the current weather in San Francisco?"
python -m app.mcp_agent "Explain what dependency injection is."

Ожидается:

  • Вопрос о погоде → логи покажут model_requested_tools / tool_call для get_current_weather, затем ответ о погоде

  • Вопрос о внедрении зависимостей → логи покажут финальный ответ без вызовов инструментов

Смотрите stderr на строки [mcp-agent]: обнаружение, типы вывода модели, имя/аргументы/длительность/результат вызова инструмента. Ключи API никогда не логируются.

Запуск простого приложения

При активированном виртуальном окружении и запущенном Ollama:

python -m app.plain_llm_app

Или с произвольным запросом:

python -m app.plain_llm_app "What is the Model Context Protocol in one sentence?"

Вы также можете использовать установленный консольный скрипт:

plain-llm "Hello!"

Запуск тестов

pytest

Структура проекта

weather-mcp-learning/
  README.md
  .env.example
  .gitignore
  pyproject.toml
  mcp-inspector.json
  app/
    __init__.py
    config.py
    llm_client.py
    plain_llm_app.py
    weather_client.py
    direct_weather_app.py
    mcp_server.py
    basic_mcp_client.py
    mcp_agent.py
  tests/

Примечания

  • Официальный пакет openai для Python используется в качестве совместимого с OpenAI клиента (ранее — Chat Completions; в Stage 4B — Responses API). Запросы направляются на ваш настроенный LLM_BASE_URL (по умолчанию Ollama).

  • Поиск погоды выполняется через Open-Meteo с использованием httpx (app/weather_client.py).

  • Stage 2B (direct_weather_app.py) явно координирует работу погоды → LLM; без MCP и без вызова инструментов.

  • Stage 3 использует официальный SDK mcp версии 2.0.0 (MCPServer из mcp.server) через stdio. Не используйте сторонний пакет fastmcp.

  • Stage 4A (basic_mcp_client.py) по-прежнему вызывает инструмент погоды явно (без выбора инструмента LLM).

  • Stage 4B (mcp_agent.py) позволяет модели выбирать инструменты после обнаружения MCP через Responses API.

Install Server
F
license - not found
A
quality
C
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 Servers

View all related MCP servers

Related MCP Connectors

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

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

  • WeatherAPI.com MCP — wraps WeatherAPI.com (api.weatherapi.com)

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/HumairaShaista/Weather-MCP-Learning'

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