Skip to main content
Glama

livetrack-mcp

Garmin LiveTrack을 폴링하고, 시계열 데이터를 SQLite에 저장하며, claude-runner를 통해 10분마다 Claude 분석을 트리거하는 자율형 MCP 서버입니다.

아키텍처

Garmin LiveTrack URL
    │
    │  (poll every 60 s)
    ▼
livetrack-mcp (port 38100)
    ├── poller.py      — fetch trackpoints from Garmin API
    ├── store.py       — SQLite time-series persistence (/data/livetrack.db)
    ├── tracker.py     — asyncio scheduling + race-end detection
    └── analyzer.py    — build prompt, call claude-runner
         │
         │  POST /run (fire-and-forget)
         ▼
    claude-runner (port 38095)
         │
         │  claude -p <analysis prompt>
         ▼
    Claude (sonnet)
         ├── analyze timeseries
         ├── curl POST /control if thresholds need adjustment
         └── mcp__telegram__send_message → coaching push

핵심 설계: livetrack-mcp는 완전히 자율적으로 작동합니다. 경주 중에 Claude 세션을 계속 유지할 필요가 없습니다. Claude는 10분마다 상태 비저장(stateless) 분석 함수로 호출됩니다. claude-runner를 일시적으로 사용할 수 없는 경우, 다음 분석 주기에서 자동으로 재시도합니다.

Related MCP server: Garmin-Strava-mcp

MCP 도구

도구

설명

start_tracking(url, race_config)

LiveTrack 공유 URL 폴링 시작

stop_tracking()

폴링 중지 (경주 종료 시 자동 중지)

get_tracking_status()

활성 상태, 경과 시간, 데이터 지연 시간, 폴링 오류

get_timeseries(minutes=10)

SQLite의 최근 데이터

update_thresholds(updates)

경주 중 HR/파워 임계값 업데이트

trigger_analysis()

일정과 관계없이 수동으로 분석 트리거

사용자 지정 HTTP 엔드포인트

엔드포인트

메서드

설명

/control

POST

경주 중 임계값 업데이트 (Bash 도구에서 curl을 통해 Claude가 호출)

/health

GET

상태 확인 — 추적 상태 + 저장소 통계

/control 사용법 (Claude의 분석 프롬프트에서)

curl -sf -X POST http://localhost:38100/control \
  -H 'Content-Type: application/json' \
  -d '{"power_max": 150}'

허용된 필드: hr_max, hr_min, power_max, power_min, cadence_min, run_hr_max, run_hr_min, run_cadence_min

race_config 필드

필드

유형

기본값

설명

hr_max

int

—

사이클링 HR 상한 (bpm)

hr_min

int

—

사이클링 HR 하한

power_max

int

—

ERG 파워 상한 (watts)

power_min

int

—

ERG 파워 하한

cadence_min

int

—

최소 사이클링 케이던스 (rpm)

run_hr_max

int

—

달리기 HR 상한

run_hr_min

int

—

달리기 HR 하한

run_cadence_min

int

—

최소 달리기 케이던스 (spm)

poll_interval_secs

int

60

LiveTrack 폴링 주기

analyze_interval_secs

int

600

Claude 분석 트리거 주기

analyze_window_min

int

10

Claude에 전달되는 데이터 윈도우 (분)

전체 철인 3종 경기를 위한 race_config 예시

{
  "race_name": "CT2026",
  "race_type": "triathlon",
  "hr_max": 144,
  "hr_min": 115,
  "power_max": 165,
  "cadence_min": 82,
  "run_hr_max": 152,
  "run_hr_min": 125,
  "run_cadence_min": 165,
  "poll_interval_secs": 60,
  "analyze_interval_secs": 600,
  "analyze_window_min": 10
}

경주 종료 감지

서버는 다음과 같은 경우 자동으로 중지됩니다:

  • 15분 이상 새로운 트랙포인트가 없는 경우 (STALE_STOP_MIN)

  • 그리고 총 경과 시간이 30분 이상인 경우 (MIN_ELAPSED_MIN)

이는 Garmin 24시간 URL 지연 문제를 처리합니다. 경주가 끝난 후에도 URL은 유효하지만, 선수가 경기를 마치면 새로운 트랙포인트가 들어오지 않습니다. 30분 최소 시간 설정은 GPS 데이터가 드문 시작 시점에 잘못된 중지를 방지합니다.

구성 (환경 변수)

변수

기본값

설명

PORT

38100

서버 포트

HOST

0.0.0.0

바인딩 주소

MCP_PATH

/mcp

MCP 엔드포인트 경로

DB_PATH

/data/livetrack.db

SQLite 데이터베이스 경로

CLAUDE_RUNNER_URL

http://localhost:38095

claude-runner 기본 URL

RUNNER_WORKSPACE

training

claude-runner 작업용 워크스페이스

LOG_LEVEL

INFO

로깅 레벨

OTEL_EXPORTER_OTLP_ENDPOINT

—

OpenTelemetry 수집기 URL (선택 사항)

배포

cd ~/ai-platform/mcps

# Build and start
docker compose up -d --build livetrack-mcp

# Logs
docker compose logs -f livetrack-mcp

# Restart
docker compose restart livetrack-mcp

# Health check
curl http://localhost:38100/health

일반적인 세션 (training 워크스페이스의 Claude를 통해)

# Start tracking
use_mcp_tool livetrack-mcp start_tracking \
  url="https://livetrack.garmin.com/session/.../token/..." \
  race_config={"hr_max": 144, "power_max": 165, "run_hr_max": 152}

# Check status
use_mcp_tool livetrack-mcp get_tracking_status

# Manual analysis trigger
use_mcp_tool livetrack-mcp trigger_analysis

# Stop (or let it auto-stop)
use_mcp_tool livetrack-mcp stop_tracking

프로젝트 구조

livetrack_mcp/
├── Dockerfile
├── pyproject.toml
├── README.md
└── src/livetrack_mcp/
    ├── __init__.py
    ├── __main__.py
    ├── otel.py        # OpenTelemetry setup
    ├── poller.py      # Garmin LiveTrack URL parsing + HTTP fetch
    ├── store.py       # SQLite time-series (sqlite3 + asyncio.to_thread)
    ├── tracker.py     # Scheduling (asyncio.create_task) + race-end detection
    ├── analyzer.py    # Prompt builder + claude-runner caller
    └── server.py      # FastMCP tools + /control + /health

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server that connects Garmin Connect data to Claude, enabling training analysis, recovery checks, and personalized plans based on real metrics like HRV, training load, and activities.
    21
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Local MCP server that connects Claude Desktop with Garmin and Apple Health data to read training and recovery, estimate heart rate and pace zones, analyze performance, and create structured workouts.
    22
    MIT