garmin-local-mcp
Almacén de datos de Garmin local primero: sincroniza una vez en SQLite que posees, luego analiza tendencias, correlaciones, líneas base y anomalías sin conexión, incluso cuando la API de Garmin falla.
Documentación
garmin-local-mcp
Almacén de datos Garmin local-first con un servidor MCP de grado analítico. Sincroniza una vez, analiza para siempre, incluso cuando la API está caída.

¿Por qué otro MCP de Garmin?
Todos los servidores MCP de Garmin existentes siguen el mismo diseño: un envoltorio fino en vivo alrededor de la API no oficial y con límite de tasa de Garmin. Cada pregunta que hace tu asistente de IA se convierte en una o más llamadas en vivo a la API que devuelven enormes blobs JSON crudos (una sola respuesta cruda de sueño ocupa alrededor de 230 KB). Preguntas de varios meses como "¿cómo se correlaciona mi sueño con la carga de entrenamiento?" son poco prácticas, y cuando Garmin cambia su autenticación (como hizo en marzo de 2026, rompiendo todo el ecosistema), esos servidores quedan completamente a oscuras, incluso para datos que ya obtuvieron ayer.
Este proyecto invierte la arquitectura:
- Sincroniza una vez, analiza para siempre. Sincronización incremental en un almacén local: instantáneas JSON crudas e inmutables más una base de datos SQLite, en un directorio que tú posees.
- Análisis del lado del servidor, respuestas compactas. Tendencias, correlaciones, líneas base personales y detección de anomalías se calculan localmente y se devuelven como tablas columnares pequeñas en una sola llamada de herramienta. Las respuestas típicas son menores de 2 KB, así que nada inunda el contexto del modelo.
- Resiliencia sin conexión. Una rotura de la API solo pausa las nuevas sincronizaciones. Cada consulta sobre el historial ya sincronizado sigue funcionando.
- Una alternativa sin autenticación. Un decodificador independiente para los mensajes FIT de bienestar no documentados de Garmin (puntuación de sueño, HRV, temperatura de la piel, etapas del sueño, siestas) ingiere paquetes exportados manualmente sin necesidad de iniciar sesión. Ningún otro MCP de Garmin incluye esto.
- Herramientas curadas. 12 herramientas componibles, no 110.
| garmin-local-mcp | MCPs de Garmin típicos con envoltorio de API | |
|---|---|---|
| Almacén de datos local que posees | Sí (JSON crudo + SQLite) | No |
| Funciona sin conexión tras una rotura de la API | Sí (análisis sobre historial sincronizado) | No |
| Análisis del lado del servidor (tendencias, correlaciones, líneas base, anomalías) | Sí | No (paso directo de JSON crudo) |
| Disciplina en el tamaño de las respuestas | Tablas columnares compactas, típicamente < 2 KB | Cargas útiles crudas, hasta cientos de KB |
| Ruta de ingesta sin autenticación | Sí (importación de paquete FIT) | No |
| Número de herramientas | 12 curadas | A menudo de 20 a 110+ |
Pruébalo sin una cuenta de Garmin
Si no tienes un Garmin, o solo quieres ver qué devuelven las herramientas antes de entregar credenciales, siembra un almacén sintético:
pip install garmin-local-mcp
garmin-local-mcp --data-dir ~/.garmin-mcp-demo demo
garmin-local-mcp --data-dir ~/.garmin-mcp-demo serve
Eso genera 180 días en cada tabla, y luego los sirve a través de MCP. Sin inicio de sesión, sin red, sin cuenta.
Los datos se generan en lugar de registrarse, pero no son aleatorios. Un factor de recuperación latente eleva el HRV mientras la frecuencia cardíaca en reposo baja, la carga de entrenamiento eleva la frecuencia cardíaca en reposo del siguiente día, una ventana de enfermedad de seis días se sitúa en medio del rango, y algunas noches de sueño faltan deliberadamente. Así que las herramientas de análisis tienen algo real que encontrar:
| Pregunta | Devuelve |
|---|---|
correlate(hrv, resting_hr) | alrededor de −0.5, una relación inversa genuina |
correlate(training_load, resting_hr, scan_lags=True) | ~0 en el desfase 0, +0.45 en el desfase 1 — el efecto es al día siguiente |
anomalies() | la ventana de enfermedad, marcada a la vez en frecuencia cardíaca en reposo, HRV, temperatura de la piel, SpO2 y puntuación de sueño |
gaps() | las noches de sueño faltantes |
sync_status informa demo_store: true en estos almacenes, así que un asistente nunca puede presentar números generados como mediciones reales. El generador es determinista — --seed reproduce un almacén exactamente, y --days cambia el rango. demo se niega a sobrescribir una base de datos que no generó.
Inicio rápido
Requiere Python 3.12+.
pip install garmin-local-mcp
O ejecútalo sin instalarlo, mediante uv:
uvx garmin-local-mcp --help
1. Inicia sesión una vez (MFA compatible; los tokens persisten localmente, así que las ejecuciones futuras nunca piden contraseña):
garmin-local-mcp login
2. Rellena tu historial. La sincronización es reanudable, segura de interrumpir y limitada para ser cortés con los servidores de Garmin. Un año de historial son aproximadamente 1.800 solicitudes; para rellenos largos, inícialo y déjalo correr (funciona bien durante la noche). Si recibe un límite de tasa o se interrumpe, vuelve a ejecutar el mismo comando y se reanuda donde se quedó.
garmin-local-mcp sync --from 2026-01-01
3. Registra el servidor MCP con tu cliente (consulta Configuración del cliente para Claude Desktop, Cursor y otros clientes):
claude mcp add --scope user garmin -- garmin-local-mcp serve
4. Haz preguntas. Ejemplos de lo que Claude ahora puede responder desde tu almacén local en una o dos llamadas de herramienta:
- "¿Cómo se correlaciona mi puntuación de sueño con la frecuencia cardíaca en reposo del día siguiente?"
- "¿Cuáles fueron mis días de HRV anómalos este trimestre?"
- "Muestra la carga de entrenamiento semanal frente al sueño de los últimos 3 meses."
Configuración del cliente
El servidor habla stdio, así que cualquier cliente MCP funciona. pip install garmin-local-mcp primero (o usa las variantes uvx a continuación, que no necesitan nada instalado más allá de uv).
Claude Code
claude mcp add --scope user garmin -- garmin-local-mcp serve
Claude Desktop, con un clic: descarga garmin-local-mcp-x.y.z.mcpb desde la última versión, luego en Claude Desktop abre Configuración > Extensiones > Configuración avanzada, haz clic en "Instalar extensión…" y selecciona el archivo. Requiere uv en tu PATH; la extensión instala y ejecuta el servidor desde PyPI mediante uvx, así que no se necesita configuración manual de Python. Si el diálogo de instalación advierte sobre un Python >=3.12 faltante, puedes ignorarlo: uv proporciona su propio intérprete.
Claude Desktop, manual (Configuración, luego Desarrollador, luego Editar configuración; añade a claude_desktop_config.json):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}
Cursor (~/.cursor/mcp.json, o .cursor/mcp.json en un proyecto):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}
Cualquier otro cliente stdio / sin instalación local (requiere uv):
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": ["garmin-local-mcp", "serve"]
}
}
}
Nota: login y el relleno inicial sync son pasos de CLI (consulta Inicio rápido); el propio servidor MCP nunca solicita credenciales.
Las 12 herramientas
| Herramienta | Qué hace |
|---|---|
auth_status | Comprueba si existen tokens de Garmin Connect almacenados (úsalo antes de sincronizar, o después de un error de autenticación). |
sync | Obtiene hasta 60 días de Garmin Connect al almacén local (por defecto: los últimos 30 días terminando ayer; los rellenos grandes pertenecen a la CLI). |
sync_status | Cobertura de datos local por tabla, última hora de sincronización y errores de sincronización pendientes. |
get_day | Una vista combinada de un solo día: bienestar, sueño, HRV, estado de entrenamiento, puntuaciones de rendimiento, actividades y banderas de calidad de datos. |
query_metrics | Serie temporal columnar para una o más métricas entre dos fechas, con agregación diaria/semanal/mensual y estadísticas opcionales. |
correlate | Correlación de Pearson/Spearman entre dos métricas, con soporte de desfase diario y un escaneo opcional sobre desfases -7..+7. |
baselines | Banda personal de media +/- desviación estándar por métrica sobre una ventana móvil (por defecto 28 días), para juzgar qué es normal para este usuario. |
anomalies | Días atípicos (desviaciones de puntuación z) y rachas sostenidas (5+ días consecutivos a un lado de la media). |
list_activities | Actividades recientes de más nueva a más antigua como tabla compacta, filtrable por tipo, rango de fechas y distancia mínima. |
get_activity | Fila de resumen completa almacenada para una actividad (solo campos de resumen, sin GPS ni flujos de muestras). |
gaps | Días faltantes por tabla más errores de sincronización sin resolver, para encontrar huecos que valga la pena re-sincronizar antes de sacar conclusiones. |
import_fit | Ingesta sin conexión y sin autenticación de un paquete FIT de bienestar de Garmin exportado manualmente. |
Solo sync y import_fit escriben algo, y solo dentro del directorio de datos. El servidor nunca solicita: los problemas de autenticación vuelven como errores estructurados con una pista que apunta a la CLI de inicio de sesión.
Los nombres de métricas disponibles incluyen resting_hr, sleep_score, hrv, steps, stress_avg, body_battery_high, skin_temp_dev_c, vo2max, fitness_age, achievable_fitness_age, training_load, endurance_score, hill_score, readiness_score, race_5k_s, y alrededor de 35 más; cualquier herramienta a la que se le dé un nombre desconocido devuelve la lista completa.
Puntuaciones de rendimiento
Las puntuaciones periódicas de forma física de Garmin llegan a su propia tabla performance: puntuación de resistencia, puntuación de colina (con sus sub-puntuaciones de resistencia y fuerza), disposición para entrenar (puntuación, nivel, tiempo de recuperación) y predicciones de carrera para 5k, 10k, media y maratón completa (todas en segundos).
Estas se actualizan al ritmo propio de Garmin en lugar de diariamente, así que performance está deliberadamente excluido de gaps — un día sin una nueva puntuación de resistencia es normal, no un hueco. Las predicciones de carrera y la puntuación de colina solo se mueven después de actividad de carrera calificada, así que largos tramos de nulos son esperables para cualquiera cuyo entrenamiento sea principalmente senderismo, ciclismo o trabajo de fuerza.
Diseño y propiedad de los datos
Todo vive en un directorio que tú posees (por defecto ~/.garmin-mcp, sobrescribible con la variable de entorno GARMIN_MCP_DATA_DIR o --data-dir):
~/.garmin-mcp/
├── config.toml # optional settings
├── tokens/ # Garmin Connect session tokens
├── raw/daily/YYYY/YYYY-MM-DD/<endpoint>.json # immutable raw API snapshots
├── raw/activities/<activity_id>.json # one snapshot per activity
└── garmin.db # SQLite warehouse
Las instantáneas JSON crudas son la fuente de verdad y nunca se sobrescriben. La base de datos SQLite es un índice derivado y reconstruible: garmin-local-mcp reparse la reconstruye desde las instantáneas crudas completamente sin conexión, que es la vía de escape universal para la evolución del esquema y las correcciones del analizador. Tus datos nunca salen de tu máquina.
Nota sobre la calidad de los datos
Los relojes Garmin informan una frecuencia cardíaca en reposo provisional en el dispositivo que puede divergir bruscamente del valor finalizado de Garmin Connect en noches con muestreo escaso. Un caso real observado: el reloj informó 69 lpm en el dispositivo mientras Garmin Connect luego finalizó la misma noche en 56 lpm.
Este proyecto maneja eso de dos maneras:
- La sincronización de la API almacena el valor finalizado de Garmin Connect.
- El importador FIT verifica cruzadamente el valor provisional en el dispositivo contra el mínimo de frecuencia cardíaca nocturno. Una frecuencia cardíaca en reposo que se sitúa más de 10 lpm por encima de la muestra nocturna más baja es una tasa que el reloj nunca observó realmente; se marca (
rhr_far_above_hr_floor) y se retiene, dejando el campo para que la API lo rellene en lugar de almacenar un número engañoso.
El registro escaso de etapas del sueño se marca de la misma manera (sparse_sleep_stage_logging), y las banderas aparecen en get_day para que la capa de análisis sepa qué números confiar.
Manual de funcionamiento sin conexión / de respaldo
Si Garmin vuelve a romper la API no oficial (ya lo ha hecho antes):
- Todo lo analítico sigue funcionando. Todas las herramientas de consulta, correlación, línea base, anomalía y huecos se ejecutan sobre tu historial local ya sincronizado. Solo se pausan las nuevas sincronizaciones.
- Sigue ingiriendo sin autenticación. Descarga un paquete FIT diario del sitio web de Garmin Connect e impórtalo localmente (pasos exactos a continuación).
garmin-local-mcp import-fit <folder>decodifica el paquete con cero autenticación y llena los días de hueco. Las filas provenientes de FIT nunca sobrescriben las filas provenientes de la API (a menos que pases--force). - Reanuda cuando la comunidad se ponga al día. Observa el proyecto python-garminconnect para una corrección, actualiza y ejecuta
garmin-local-mcp syncde nuevo. Gracias al estado de sincronización reanudable, retoma exactamente donde se detuvo.
Descargar un paquete de bienestar, paso a paso
-
Inicia sesión en connect.garmin.com en cualquier navegador.
-
Ve directamente a https://connect.garmin.com/app/settings/accountInformation (o haz clic en tu avatar en la esquina superior derecha, luego Configuración, luego Información de la cuenta en la barra lateral izquierda).
-
Desplázate al fondo de la página, a la sección titulada Exportar datos de bienestar ("Descarga tus archivos FIT de bienestar de un día específico. Esto incluye datos como pasos, sueño, estrés, HRV y más.").
-
Elige una fecha en el campo Fecha y haz clic en Exportar. Tu navegador descarga un pequeño zip para ese solo día, que contiene aproximadamente de 12 a 15 archivos
.fitbinarios (*_WELLNESS.fit,*_SLEEP_DATA.fit,*_HRV_STATUS.fit,*_SKIN_TEMP.fit,*_METRICS.fit, y similares). -
Descomprímelo en una carpeta y ejecuta:
garmin-local-mcp import-fit "path/to/unzipped/folder" -
Repite para cada día faltante (un paquete por fecha). La herramienta
gapsogarmin-local-mcp statuste dice qué días necesitan rellenarse.
Dos cosas que vale la pena saber:
- El sueño nocturno pertenece a la fecha de despertar. Para obtener el sueño de anoche, exporta la fecha de ayer si dormiste hasta esta mañana, es decir, la fecha en la que te despertaste.
- Esta exportación diaria es instantánea y separada de la exportación completa de la cuenta de Garmin (el enlace "Data Management" en la misma página), que es un archivo masivo que puede tardar días en llegar por correo electrónico y no es lo que
import-fitespera.
Configuración
config.toml opcional en el directorio de datos:
| Clave | Predeterminado | Significado |
|---|---|---|
timezone | Zona horaria del sistema | Nombre IANA (p. ej. America/Denver) utilizado para calcular "ayer" para los rangos de sincronización |
units | metric | metric o statute |
request_delay_seconds | 1.0 | Retraso entre solicitudes de API durante la sincronización |
baseline_window_days | 28 | Ventana de retroceso predeterminada para la herramienta baselines |
Variables de entorno:
| Variable | Significado |
|---|---|
GARMIN_MCP_DATA_DIR | Sobrescribir el directorio de datos (predeterminado ~/.garmin-mcp) |
GARMINTOKENS | Sobrescribir la ubicación del almacén de tokens (predeterminado <data_dir>/tokens) |
GARMIN_EMAIL / GARMIN_PASSWORD | Opcional, para re-inicio de sesión no interactivo; cuando se establecen, garmin-local-mcp login omite los avisos (el MFA puede seguir solicitando si tu cuenta lo requiere) |
Desarrollo
python -m venv .venv
.venv/bin/pip install -e .[dev] # Windows: .venv\Scripts\pip install -e .[dev]
pytest
ruff check .
El conjunto de pruebas se ejecuta completamente sin conexión contra archivos JSON sanitizados y muestras FIT pequeñas; CI nunca toca la API en vivo.
Aviso legal
Este proyecto no está afiliado, respaldado ni apoyado por Garmin Ltd. Utiliza la biblioteca comunitaria python-garminconnect con tus propias credenciales para acceder a tus propios datos. Las API de Garmin son no oficiales y pueden cambiar o romperse en cualquier momento; cuando eso suceda, tu historial sincronizado sigue siendo totalmente utilizable y la ruta de importación FIT sigue funcionando.
Todos los datos permanecen en tu máquina. Nada se comunica con el exterior: sin telemetría, sin servicios de terceros, sin nube. Trata tu directorio de datos como el registro de salud personal que es, y nunca lo confirmes en un repositorio.
Licencia
MIT