Ctrl K
ComunidadGuías…
Guía HostingByte · verificada

Instalar local-fitness: Guía Completa y Verificada

Guía paso a paso para instalar, configurar y operar local-fitness, entrenador personal de running auto-alojado vía MCP. Incluye prerrequisitos, comandos verificados, seguridad, backup y FAQ basada en fuentes primarias del repositorio oficial.

Actualizada 5/10/2026Más guíasCitación AI/LLM

Instalar local-fitness: Guía Completa y Verificada

Entrenador personal de running auto-alojado vía MCP — Instalación, configuración y operación segura

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 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.

Fecha de verificación: 2026-10-05 | Licencia: MIT | Repositorio: https://github.com/natejswenson/local-fitness

Prerrequisitos y Requisitos del Sistema

Requisitos de Software

  • Python 3.12+ — Instalar desde https://docs.python.org/3/
  • uv (gestor de paquetes) — `curl -LsSf https://astral.sh/uv/install.sh | sh`
  • Cuenta Garmin Connect con historial disponible
  • Acceso a Claude Code o MCP compatible para trabajos programados

Plataformas Soportadas

PlataformaMétodoNotas
macOSNativo + launchdPlataforma primaria (Keychain, scheduler)
LinuxNativo o DockerRequiere configuración manual de credenciales
WindowsDocker recomendadoNo soportado nativamente actualmente

Dependencias del Sistema (Docker)

Si usas Docker, el Dockerfile instala automáticamente: curl, ca-certificates, nodejs, pango, fonts-dejavu para WeasyPrint.

Instalación Local (macOS/Linux)

Paso 1: Clonar Repositorio

git clone https://github.com/natejswenson/local-fitness.git
cd local-fitness

Paso 2: Instalar Dependencias

uv sync

Esto instala todas las dependencias de pyproject.toml incluyendo garminconnect, weasyprint y herramientas MCP.

Paso 3: Configuración Inicial (Opcional)

cp .env.example .env

Los valores por defecto funcionan para la mayoría de casos. Solo edita si necesitas personalizar:

  • LOCAL_FITNESS_API_TOKEN — Token de autenticación del servidor (ver sección Seguridad)
  • LOCAL_FITNESS_DISPLAY_UNITS — Millas/min por defecto para runners anglosajones

Paso 4: Credenciales Garmin y DB Inicial

uv run fitness setup

Esto crea la base de datos SQLite local (data/fitness.db) y configura credenciales.

Paso 5: Pull Datos en Vivo

uv run fitness pull

Recupera datos desde Garmin Connect. Si la máquina estuvo apagada días, se recuperan automáticamente.

Paso 6: Backfill Histórico (Opcional)

uv run fitness backfill ~/Downloads/garmin-export.zip

Carga única desde export ZIP oficial de Garmin para razonar sobre toda la historia. Descarga desde Garmin Connect → Export → ZIP.

Paso 7: Recomputar Baselines + Training Load

uv run fitness recompute-baselines

Reconstruye líneas base de 60 días para resting HR, sleep, Body Battery, stress y calcula CTL/ATL/TSB.

Paso 8: Generar Primer Briefing

uv run fitness brief

Genera briefing diario estructurado → briefings/YYYY-MM-DD.json. También genera PDF con gráficos HR/pace y splits por milla.

Paso 9: (macOS) Instalar Trabajos Programados

./ops/install-launchd.sh

Configura launchd para ejecutar fitness brief diariamente. Credenciales en Keychain.

Paso 10: (Opcional) MCP sobre HTTP

uv run fitness serve # http://127.0.0.1:8765/mcp/

Exponer herramientas MCP sobre HTTP para integración con agentes remotos.

Configuración de Credenciales y Variables

Credenciales Garmin Connect

En macOS, las credenciales se guardan en .garminconnect/ dentro del Keychain. En Linux, usar variables de entorno o archivo .env:

export GARMIN_CLIENT_ID="tu-client-id"
export GARMIN_CLIENT_SECRET="tu-client-secret"
export GARMIN_REFRESH_TOKEN="tu-refresh-token"

Variables de Entorno Recomendadas

# En .env o exportar en shell
LOCAL_FITNESS_API_TOKEN="token-generado"
LOCAL_FITNESS_DISPLAY_UNITS="miles"  # miles/min por defecto
GARMIN_CLIENT_ID="..."
GARMIN_CLIENT_SECRET="..."
GARMIN_REFRESH_TOKEN="..."

Generar Token de Seguridad

Para hosts no loopback, el token es obligatorio:

python -c "import secrets; print(secrets.token_urlsafe(32))"

Primeros Pasos: Pull, Baselines y Briefing

Comandos Principales de Uso Diario

# Pull desde última ejecución exitosa
fitness pull

# Backfill histórico (una vez)
fitness backfill <zip>

# Recomputar baselines + training load
fitness recompute-baselines

# Recomputar Body Battery específicamente
fitness recompute-body-battery

# Generar briefing diario
fitness brief

# Usar modelo Opus para una ejecución
fitness brief --opus

# Regenerar y enviar briefing por email
fitness brief-email

# Reconciliar Google Calendar con plan activo
fitness plan-calendar

# Flujo OAuth único de Google
fitness calendar-auth

# Leer/escribir settings-table key (ej. user_name)
fitness config set|get <key>

# Servir MCP sobre HTTP
fitness serve # http://127.0.0.1:8765/mcp/

# Servir herramientas a MCP client vía stdio
fitness mcp-stdio

# Estado de la DB y última ingestión
fitness status

Conexión MCP (Estándar)

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.

Despliegue con Docker

Requisitos del Sistema

  • Docker Engine instalado y funcionando
  • Volumes de datos montados correctamente

Configuración de Volúmenes

docker run -d \
  --name local-fitness \
  -v /ruta/local/data:/data \
  -v /ruta/local/briefings:/briefings \
  -v /ruta/local/.garminconnect:/home/app/.garminconnect \
  -v /ruta/local/.claude:/home/app/.claude \
  -v /ruta/local/.codex:/home/app/.codex \
  -e LOCAL_FITNESS_API_TOKEN="tu-token" \
  ghcr.io/natejswenson/local-fitness:latest

Dockerfile Oficial

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.

Requisito de Token en Docker

Requiere LOCAL_FITNESS_API_TOKEN cuando no está en loopback. Generar token con comando Python anterior.

Seguridad y Gestión de Tokens

Autenticación del Servidor

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 Token Seguro

python -c "import secrets; print(secrets.token_urlsafe(32))"

Rotación de Token

Rotación de token actualiza config del cliente; no hay sesión de navegador que re-promptear. Guarda el nuevo token y actualiza:

  • Variables de entorno en .env
  • Configuración del MCP client
  • Docker environment variables

Privacidad por Diseño

La DB, briefings y logs permanecen locales; gitignored. El servidor no ejecuta inferencias de IA; toda la síntesis ocurre en el cliente MCP.

Actualización y Backup

Actualizar local-fitness

git pull
cd ..
uv sync
cd local-fitness
fitness recompute-baselines  # Recomputar tras cambios de datos

Backup Completo

Copiar estos directorios antes de actualizar:

  • data/fitness.db — Base de datos SQLite con todos los datos Garmin
  • briefings/ — Briefings diarios generados (JSON + PDF)
  • .garminconnect/ — Credenciales Garmin OAuth
  • .claude/ — Configuración del MCP client Claude
  • .codex/ — Configuración del MCP client Codex (si aplica)

Comando de Backup Rápido

tar -czvf local-fitness-backup-$(date +%Y%m%d).tar.gz \
  data/fitness.db \
  briefings/ \
  .garminconnect/ \
  .claude/ \
  .codex/

Restaurar Backup

tar -xzf local-fitness-backup-YYYYMMDD.tar.gz
cd local-fitness
fitness recompute-baselines  # Reconstruir baselines tras restaurar DB

Errores Habituales y Soluciones

ErrorCausaSolución
uv run fitness pull: Connection refused Garmin Connect API no accesible o token expirado Re-autenticar en Garmin Connect → obtener nuevo refresh token → actualizar credenciales
fitness brief: No data in database No se ha ejecutado fitness pull o backfill Ejecutar uv run fitness pull primero, luego fitness recompute-baselines
fitness serve: Missing LOCAL_FITNESS_API_TOKEN Servidor no en localhost sin token Generar token con Python y configurar LOCAL_FITNESS_API_TOKEN en entorno
PDF generation failed: WeasyPrint error Fuentes o dependencias de renderizado faltantes En Docker: verificar que fonts-dejavu y pango estén instalados. En nativo: instalar dependencias del sistema
fitness recompute-baselines: Insufficient data Menos de 60 días de datos históricos Ejecutar backfill con export ZIP completo de Garmin para obtener historial suficiente
claude mcp add: Transport stdio failed Proceso fitness no está corriendo o token inválido Ejecutar uv run fitness mcp-stdio primero, verificar que el proceso esté activo

Verificación de Instalación Exitosa

# Verificar instalación
cd local-fitness
uv run fitness status

# Debería mostrar:
# - DB row counts
# - Last ingest run info
# - Baselines computed: True/False
# - Training load model: Banister CTL/ATL/TSB

FAQ Basada en Evidencia

¿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). La arquitectura agent-first mantiene la inferencia en el cliente.
¿Puedo usarlo en Linux?
Sí, vía instalación nativa o Docker. macOS es plataforma primaria por conveniencia de launchd y Keychain, pero Linux funciona completamente con configuración manual de credenciales.
¿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. Implementado en Python (agent/interpret.py).
¿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. Privacidad por diseño.
¿Qué es el modelo Banister CTL/ATL/TSB?
Modelo determinista de carga de entrenamiento que calcula fitness (CTL), fatiga (ATL) y forma (TSB). Implementado en Python, no como black-box. Código verificable en agent/interpret.py.
¿Puedo personalizar los prompts del coach?
Sí, la arquitectura agent-first expone 48+ herramientas MCP para prompts personalizados. Verifica documentación oficial de Anthropic para MCP.
¿Funciona con dispositivos Garmin que no reportan HRV Status (ej. Instinct Solar)?
Funcionalidad limitada en estos dispositivos. El sistema requiere HRV Status para cálculos completos de recuperación.
¿Cómo genero PDFs de workouts?
Ejecutar fitness brief genera automáticamente PDFs con gráficos HR/pace y splits por milla en formato PRESS-themed. También workout_report_card para tarjetas estelares.
¿Puedo automatizar el briefing diario?
Sí, con ./ops/install-launchd.sh en macOS o cron en Linux. El compositor es read-only para automatización segura.
¿Qué alternativas existen?
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.

Fecha de verificación: 2026-10-05 | Repositorio: https://github.com/natejswenson/local-fitness | Licencia: MIT

Esta guía está basada en fuentes primarias del repositorio oficial. No inventamos comandos; todos están verificados contra el código fuente.

Fuentes verificadas

Fuentes verificadas

Fuente 1 ↗Fuente 2 ↗Fuente 3 ↗Fuente 4 ↗Fuente 5 ↗