Ctrl K
ComunidadGuías…
✓ ficha editorial verificadaPythonclaudefitnessgarminmcp

local-fitness — Entrenador de Running Auto-alojado vía MCP

local-fitness es un entrenador personal de running auto-alojado que transforma datos Garmin Connect en informes diarios estructurados, evaluaciones estelares de sesiones y planes adaptativos mediante MCP. Arquitectura agent-first con análisis determinista en Python (CTL/ATL/TSB, baselines móviles 60 días). Privacidad por diseño: todo local.

local-fitness

Entrenador personal de running auto-alojado vía MCP

local-fitness es un entrenador personal de running auto-alojado que transforma datos de Garmin Connect en informes diarios estructurados, evaluaciones estelares de sesiones y planes adaptativos mediante el Protocolo de Contexto del Modelo (MCP). Arquitectura agent-first: el servidor actúa como capa de transporte determinista; toda la síntesis conversacional ocurre en el cliente agente.

¿Qué es y para quién?

Aplicación auto-alojada para runners que desean coaching personalizado basado en datos reales de su Garmin. Ideal para atletas individuales que valoran privacidad, transparencia algorítmica y control total sobre sus métricas. No es un servicio multi-tenant: una cuenta Garmin, una base SQLite local.

Casos de uso

  • Generación automática de informes diarios de estado físico y recuperación (frecuencia cardíaca en reposo, sueño, Body Battery, estrés)
  • Evaluación determinista de sesiones con puntuación estelar (1-5 estrellas) basada en desviaciones relativas normalizadas
  • Redacción de planes de entrenamiento adaptativos mediante herramientas MCP expuestas a agentes
  • Sincronización de calendario Google con el plan activo para gestión de citas

Características

  • Daily auto-pull: desde Garmin Connect vía garminconnect — recupera automáticamente si la máquina estuvo apagada días.
  • Historical backfill: carga única desde export ZIP oficial de Garmin para razonar sobre toda la historia.
  • Pre-computed baselines: 60-day rolling mean/SD para resting HR, sleep, Body Battery, stress.
  • Modelo Banister CTL/ATL/TSB: fitness / fatiga / forma calculado determinísticamente.
  • Agent-first: coach vive en MCP client (Claude Desktop, Code, Mobile). El servidor no realiza inferencias de IA.
  • Scheduled daily brief: fitness brief genera JSON y PDF; compositor read-only para automatización segura.
  • Star-rated report cards: workout_report_card juzga sesiones con 1-5 estrellas, incluyendo splits por milla y gráfico HR/pace en PDF PRESS-themed.
  • Deterministic interpretation: cada clasificador está implementado en Python (agent/interpret.py); el modelo solo formula juicios, no los deriva.
  • Runner-facing units: distancias y pace en millas/min por defecto (LOCAL_FITNESS_DISPLAY_UNITS).
  • Privacy by default: base de datos, briefings y logs permanecen locales; gitignored.

Arquitectura

Flujo determinista: Garmin Connect → SQLite (data/fitness.db) → baselines/CTL-ATL-TSB → capa de herramientas MCP. El servidor no ejecuta inferencias; expone recursos y herramientas sobre MCP para que el agente realice síntesis conversacional, redacción de planes y generación de informes.

Garmin Connect ──pull──> SQLite (data/fitness.db) ──> baselines / CTL-ATL-TSB
 │
 deterministic tool layer ─────┤
 │
 ┌──────────────────────────────────────┴───────────────┐
 MCP server scheduled `fitness brief`
 (Claude, Codex: composes brief → coach + prompts, tools, briefings/*.json)
 resources, write surface

Requisitos reales

  • Python 3.12+ y uv (gestor de paquetes)
  • Cuenta Garmin Connect con historial
  • Acceso a Claude Code o MCP compatible para trabajos programados
  • macOS es plataforma primaria (scheduler usa launchd, credenciales en Keychain). Linux/otros funcionan vía Docker o instalación nativa.

Instalación/despliegue

Local (macOS/Linux)

# 1. Clonar e instalar deps + comando `fitness`
git clone https://github.com/natejswenson/local-fitness.git
cd local-fitness
uv sync

# 2. Configuración (opcional, defaults funcionan)
cp .env.example .env

# 3. Credenciales Garmin y DB inicial
uv run fitness setup

# 4. Pull datos en vivo
eu run fitness pull

# 5. Backfill histórico (opcional, tras export ZIP de Garmin)
uv run fitness backfill ~/Downloads/garmin-export.zip

# 6. Recomputar baselines + training load
uv run fitness recompute-baselines

# 7. Generar briefing
eu run fitness brief

# 8. (macOS) Instalar trabajos programados
./ops/install-launchd.sh

# 9. (Opcional) MCP sobre HTTP
uv run fitness serve # http://127.0.0.1:8765/mcp/

Docker

El Dockerfile usa python:3.12-slim, instala curl, ca-certificates, nodejs, pango, fonts-dejavu para WeasyPrint. Clona @anthropic-ai/claude-code@2.1.119 y @openai/codex@0.157.1. Monta volúmenes en /data, /briefings, /home/app/.garminconnect, /home/app/.claude, /home/app/.codex. Requiere LOCAL_FITNESS_API_TOKEN cuando no está en loopback.

Uso

fitness pull # pull since last success
fitness backfill <zip> # one-time full-history load from Garmin export ZIP
fitness recompute-baselines # rebuild 60-day baselines + CTL/ATL/TSB
fitness recompute-body-battery # re-derive body-battery aggregates from samples
fitness brief # pull + recompute + briefing → briefings/YYYY-MM-DD.json
fitness brief --opus # use Opus model for one run
fitness brief-email # regenerate today's brief and email it
fitness plan-calendar # reconcile Google Calendar to active plan
fitness calendar-auth # one-time Google OAuth flow
fitness config set|get <key> # read/write settings-table key (e.g. user_name)
fitness serve # MCP over HTTP at http://127.0.0.1:8765/mcp/
fitness mcp-stdio # serve tools to MCP client over stdio
fitness status # DB row counts + last ingest run info

MCP — Interacción vía agente

El MCP es la única forma de interactuar con el coach; no hay UI web. Se exponen 48+ herramientas (47 sobre HTTP), 2 prompts y 2 recursos. Conexión local sin token: claude mcp add --transport stdio fitness -- uv run fitness mcp-stdio. Conexión HTTP con token: claude mcp add --transport http fitness https://<host>/mcp/ --header "Authorization: Bearer $TOKEN".

Prompts principales:

  • coach: ensambla snapshot diario completo (métricas vs baseline, training load, workouts recientes) + persona coach + preferencias guardadas.
  • brief: compone briefing estructurado diario y lo persiste vía save_brief.

Seguridad

El servidor autentica cada ruta no pública (/health excluido) con token bearer LOCAL_FITNESS_API_TOKEN. En hosts no loopback, el token es obligatorio; el servidor se refusa a iniciar sin él. Generar: python -c "import secrets; print(secrets.token_urlsafe(32))". Rotación de token actualiza config del cliente; no hay sesión de navegador que re-promptear.

Actualización/backup

Actualizar: git pull, luego uv sync. Recomputar baselines tras cambios de datos: fitness recompute-baselines.

Backup: copiar data/fitness.db, briefings/, y credenciales (.garminconnect/, .claude/, .codex/). El servidor no ejecuta inferencias; no hay endpoints costosos que drenen suscripción.

Ventajas

  • Arquitectura agent-first mantiene inferencia en el cliente, no en servidor
  • Análisis determinista en Python con código interpretable y verificable (agent/interpret.py)
  • Privacidad por diseño: toda la DB y logs permanecen locales sin salida de datos innecesaria
  • Modelo Banister CTL/ATL/TSB implementado determinísticamente, no como black-box
  • PDF exports con gráficos HR/pace y splits por milla en formato PRESS-themed

Límites

  • No incluye interfaz web; toda interacción requiere cliente MCP compatible
  • Funcionalidad limitada en dispositivos Garmin que no reportan HRV Status (ej. Instinct Solar)
  • Dependencia de suscripción a Claude para agente interactivo y trabajos programados
  • Requiere configuración manual de credenciales Garmin (Keychain o env vars)

Alternativas reales

Soluciones SaaS como TrainingPeaks, Strava Segments Pro o Garmin Connect IQ ofrecen dashboards web y apps móviles nativas. local-fitness se diferencia por: análisis determinista verificable, privacidad total (todo local), arquitectura agent-first que integra con tu stack MCP existente, y capacidad de personalización mediante prompts y herramientas expuestas.

FAQ

¿Funciona sin suscripción a Claude?
Sí, el servidor no ejecuta inferencias. El agente interactivo requiere MCP client con suscripción (Claude Code o compatible).
¿Puedo usarlo en Linux?
Sí, vía instalación nativa o Docker. macOS es plataforma primaria por conveniencia de launchd y Keychain.
¿Cómo se calculan las estrellas de los workouts?
Cada métrica (distance, pace, HR, continuity) reduce a una desviación relativa normalizada que pasa por una curva compartida en escala 1-5 con precisión fraccional.
¿Los datos salen de mi máquina?
No. La DB, briefings y logs permanecen locales; solo el agente lee métricas cuando lo solicita o escribe un briefing.

Relacionado en HostingByte

Alternativas y comparativas · Guías de HostingByte

Fuentes verificadas

Fuentes y verificación
Quality gate 100/100 · información trazable para SEO/GEO
Fuente 1 ↗Fuente 2 ↗Fuente 3 ↗Fuente 4 ↗Fuente 5 ↗
Citación para IA y agentes
Resumen citable, canonical y fuentes verificadas en texto plano.
llms.txt de esta ficha →