Skip to main content
Glama
SanGlaze23

polar-mcp-mini

by SanGlaze23
README.md
# polar-mcp (Python)

MCP-сервер: данные Polar Flow → Claude. Переписан с Node.js на Python.

## Что изменилось по сравнению с JS-версией

**Главное:** ушли транзакции. Прошлая версия использовала
`exercise-transactions` — это **deprecated** часть Polar API, где каждая
тренировка отдаётся ровно один раз, а потом исчезает.

Актуальный API — обычный `GET /v3/exercises?samples=true&zones=true`:
- окно 30 дней, перечитывать можно сколько угодно раз
- зоны и семплы приходят сразу, отдельные запросы не нужны
- никакого хранилища/БД не требуется

Ограничение осталось одно: отдаются только тренировки, загруженные в Flow
**после** регистрации приложения. Старые из Polar Flow недоступны.

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

| Инструмент | Что отдаёт |
|---|---|
| `get_exercises` | Тренировки за 30 дней: пульс, зоны, cardio/muscle load, Running Index, сводка по каденсу, высоте, мощности |
| `get_exercise` | Одна тренировка по id |
| `get_exercise_samples` | Сырые секундные семплы (пульс, темп, каденс, высота, мощность) |
| `get_sleep` | Сон: стадии, sleep score |
| `get_nightly_recharge` | HRV, ANS charge, восстановление |
| `get_cardio_load` | Нагрузка, strain, tolerance (без даты — 28 дней) |
| `get_continuous_hr` | Пульс в течение дня, интервал 5 мин |
| `get_daily_activity` | Шаги, калории, активные минуты |
| `get_physical_info` | Вес, рост, HRmax, пороги, VO2max из настроек Polar |

Семплы не вываливаются целиком: `get_exercises` отдаёт сводку
(min/avg/max, набор и сброс высоты), сырые точки — только по явному запросу
через `get_exercise_samples`.

## Установка с нуля

### 1. Polar client

На https://admin.polaraccesslink.com создай клиента.
Redirect URI: `http://localhost:8080/callback`
Сохрани Client ID и Client Secret.

### 2. Токен (локально, один раз)

```bash
pip install -r requirements.txt
POLAR_CLIENT_ID=... POLAR_CLIENT_SECRET=... python setup_polar_auth.py
```

Windows PowerShell:
```powershell
$env:POLAR_CLIENT_ID="..."; $env:POLAR_CLIENT_SECRET="..."; python setup_polar_auth.py
```

Скрипт выведет `POLAR_ACCESS_TOKEN` — сохрани.

### 3. Деплой на Railway

Залей в GitHub, подключи репозиторий в Railway (увидит `Dockerfile` сам).

Переменные в Railway → Variables:

| Переменная | Значение |
|---|---|
| `POLAR_ACCESS_TOKEN` | из шага 2 |
| `SHARED_SECRET` | любая длинная случайная строка (`openssl rand -hex 32`) |

`POLAR_USER_ID` больше не нужен — актуальный API работает без него.

Settings → Networking → Generate Domain.

Проверка: `curl https://твой-домен.up.railway.app/health` → `{"status":"ok"}`

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

Настройки → Connectors → Add custom connector

**Server URL:** `https://твой-домен.up.railway.app/mcp/твой_SHARED_SECRET`

Advanced settings оставить пустыми.

## Переход с JS-версии

Если JS-версия уже развёрнута и подключена:

1. Замени в репозитории `server.js`/`package.json`/`Dockerfile` на файлы отсюда
2. Удали `POLAR_USER_ID` из Railway (не мешает, но не используется)
3. `SHARED_SECRET` и `POLAR_ACCESS_TOKEN` оставь как есть
4. URL коннектора не меняется — переподключать в Claude не нужно
5. После деплоя список инструментов обновится; если Claude показывает старый —
   отключи и подключи коннектор заново

## Про типы семплов

Polar нумерует типы семплов, но в документации таблица неполная.
В `server.py` есть словарь `SAMPLE_TYPE_NAMES` с предварительным мэппингом.
В выдаче всегда присутствует `sample_type_raw`, так что при расхождении
(например, `unknown_type_8` вместо каденса) достаточно поправить словарь.