Skip to main content
Glama
KDimkuz

mcp-weather-connector

by KDimkuz
README.md
# mcp-weather-connector

MCP-сервер, который даёт ИИ-агенту доступ к прогнозу погоды через [Open-Meteo](https://open-meteo.com/) — публичное API без ключа и регистрации.

Небольшой, намеренно: репозиторий про то, **как устроен инструментальный слой для агента**, а не про погоду. Погода здесь — понятный предлог показать границу доверия между моделью и внешним миром.

## Зачем это

Model Context Protocol — способ дать языковой модели право совершать действия во внешних сервисах. Как только такое право появляется, возникает вопрос: что будет, если модель передаст в инструмент мусор, а чужой сервис в этот момент отдаст 503.

Три решения, которые в этом коде показаны явно:

**Вход от модели — недоверенный.** Модель может передать пустую строку, простыню на десять килобайт или управляющие символы. Всё это отсекается в [`server.py`](src/mcp_weather/server.py) до сетевого вызова, а не в чужом API.

**Ошибки различаются по типу.** 4xx повторять бессмысленно — это ошибка запроса, повтор её не исправит. 5xx чаще разовый сбой — один повтор с паузой. Логика в [`_get_json`](src/mcp_weather/client.py), проверяется тестами на счётчик вызовов.

**Наружу уходит текст, а не сырой JSON.** Агенту нечего домысливать и не в чем ошибиться при пересказе. Ответ 200 без нужного поля считается сбоем, а не поводом отдать пустоту.

Отдельно: число дней вне диапазона приводится к границе, а не считается ошибкой. Если модель попросила прогноз на 30 дней, полезнее отдать семь, чем уронить диалог сообщением об ошибке.

## Инструменты

| Инструмент | Что делает |
|---|---|
| `current_weather(city)` | Текущая погода: температура, ощущается как, влажность, ветер |
| `forecast(city, days=3)` | Прогноз на 1–7 дней с осадками |
| `locate(query)` | Проверяет существование населённого пункта и уточняет страну |

`locate` существует ради одного сценария: когда агент не уверен в написании, лучше уточнить у пользователя, чем молча выдать погоду не того города.

## Установка

```bash
pip install -e .
```

## Подключение к Claude Desktop

В `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "weather": {
      "command": "mcp-weather"
    }
  }
}
```

После перезапуска приложения инструменты появятся в списке доступных.

## Разработка

```bash
pip install -e ".[dev]"
pytest
ruff check .
```

Тесты покрывают то, что реально ломается: пустой и переразмеренный ввод, нечисловое количество дней, 4xx без повтора, 5xx с одним повтором, успех со второй попытки, ответ 200 без полезной нагрузки, неизвестный код погоды. HTTP замокан через `respx` — сеть в тестах не нужна.

## Структура

```
src/mcp_weather/
    client.py    — работа с Open-Meteo: типы, повторы, разбор ответа
    server.py    — MCP-слой: валидация входа и форматирование вывода
tests/
    test_tools.py
```

Сетевой код отделён от MCP-слоя намеренно: клиент тестируется сам по себе, а инструменты агента остаются тонкой обёрткой над понятными функциями.

## Лицензия

MIT

TDQS

A3.8/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: current conditions, multi-day forecast, and location validation. There is no overlap or ambiguity between them, even though two tools accept a city argument.

Naming Consistency3/5

Naming is readable but inconsistent: current_weather is a noun phrase, forecast is a bare noun, and locate is a verb. A more consistent pattern like get_current_weather, get_forecast, and validate_location would be clearer.

Tool Count5/5

Three tools is well-scoped for a weather connector. Each tool covers a necessary function without unnecessary overlap or bloat.

Completeness4/5

The core weather workflows are covered: current conditions and multi-day forecasts, with optional location validation. Minor gaps exist, such as lacking unit selection or weather alerts, but these are not essential for most use cases.

Maintenance

ActivityMaintained
ResponsivenessNo issues