Garmin Training MCP
by javipaur
README.md
# Garmin Training MCP
Servidor MCP que conecta Claude con tu cuenta de Garmin Connect para que
Claude pueda ver tus actividades, tu sueño y tus datos de recuperación, y con eso
crear y **adaptar día a día** tu plan de entrenamiento (running, natación, ciclismo,
fuerza) según tu meta.
## Modos de uso
| Modo | Transporte | Dónde corre | Ventaja |
|---|---|---|---|
| **Local** | stdio | Tu ordenador, con Claude Desktop | Cero infraestructura, cero latencia |
| **VPS (Dokploy)** | HTTP | Tu VPS, accesible por HTTPS | Accesible desde Claude Desktop, Claude Code, móvil... |
Puedes usar ambos simultáneamente: el local para uso rápido en el PC, el VPS para
cuando estés fuera o desde el móvil.
---
## 1. Instalación
```bash
cd garmin-training-mcp
python3 -m venv venv
source venv/bin/activate # en Windows: venv\Scripts\activate
pip install -r requirements.txt
```
## 2. Credenciales de Garmin
La primera vez que el servidor se conecte necesita tu email y contraseña de Garmin
Connect (las mismas que usas en la app). Después de ese primer login, el servidor
guarda un token de sesión en `~/.garmin_mcp/tokens` y **no vuelve a pedir credenciales**
(hasta que el token caduque).
```bash
export GARMIN_EMAIL="tu_email@ejemplo.com"
export GARMIN_PASSWORD="tu_contraseña"
```
## 3. Modo local (stdio con Claude Desktop)
### 3.1 Configurar Claude Desktop
Abre (o crea) el archivo de configuración de Claude Desktop:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
```json
{
"mcpServers": {
"garmin-training": {
"command": "/ruta/absoluta/a/garmin-training-mcp/venv/bin/python3",
"args": ["/ruta/absoluta/a/garmin-training-mcp/server.py"],
"env": {
"GARMIN_EMAIL": "tu_email@ejemplo.com",
"GARMIN_PASSWORD": "tu_contraseña"
}
}
}
}
```
Reinicia Claude Desktop. Verás "garmin-training" en las herramientas disponibles.
---
## 4. Modo VPS con Dokploy
### 4.1 Subir el código a GitHub
```bash
cd garmin-training-mcp
git init && git add -A && git commit -m "initial"
git remote add origin https://github.com/TU_USUARIO/garmin-training-mcp.git
git push -u origin main
```
### 4.2 Crear el proyecto en Dokploy
1. En tu VPS con Dokploy: **Projects → Create Project** → nombre `garmin-training`
2. **Applications → Deploy from GitHub** → selecciona el repo
3. **Build Settings**: Dokploy detecta el `Dockerfile` automáticamente. Si no:
- Build Pack: `Dockerfile`
- Dockerfile path: `Dockerfile`
4. **Puerto**: `8080`
### 4.3 Variables de entorno en Dokploy
En tu proyecto → **Environment** → añade:
```
GARMIN_EMAIL=tu_email@example.com
GARMIN_PASSWORD=tu_contraseña
SUPABASE_URL=https://tu-proyecto.supabase.co # opcional
SUPABASE_KEY=tu_clave_anon # opcional
MCP_PORT=8080
```
> ⚠️ Si usas Supabase, crea primero las tablas (ver sección más abajo).
### 4.4 Dominio + HTTPS
1. En Dokploy → **Domains** → añade tu dominio (ej: `garmin.tudominio.com`)
2. Dokploy configura SSL automáticamente con Let's Encrypt
3. Tu MCP server queda accesible en `https://garmin.tudominio.com/mcp/`
### 4.5 Conectar Claude al VPS
En `claude_desktop_config.json` (o `.claude/settings.json` para Claude Code):
```json
{
"mcpServers": {
"garmin-training": {
"transport": {
"type": "streamable-http",
"url": "https://garmin.tudominio.com/mcp/"
}
}
}
}
```
Reinicia Claude Desktop. Las mismas tools estarán disponibles, pero ahora
corriendo en tu VPS.
### 4.6 Probar la conexión
```bash
curl -X POST https://garmin.tudominio.com/mcp/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
---
## 5. Cómo usarlo con Claude
Ejemplos de cosas que puedes pedirle a Claude una vez conectado:
- *"Mi meta es correr una media maratón en menos de 1h50 el 15 de noviembre.
Entreno 4 días por semana. Créame un plan."*
- *"Buenos días, ¿qué toca hoy?"* → Claude usará `get_daily_briefing`
- *"¿Puedo hacer series hoy o mejor lo dejo suave?"* → `get_training_recommendation`
- *"Ayer nadé 2000m, ¿cómo voy?"* → `get_recent_activities` / `get_activity_detail`
- *"He dormido fatal esta semana, ajusta el plan"* → `get_sleep` + `save_training_plan`
- *"¿Cómo entrené el mes pasado?"* → `query_activities_by_date_range`
## 6. Herramientas (tools) que expone el servidor
| Tool | Para qué sirve |
|---|---|
| `get_recent_activities` | Actividades de los últimos N días |
| `get_activity_detail` | Detalle + parciales de una actividad concreta |
| `get_sleep` | Sueño (score, fases, horas) de los últimos N días |
| `get_recovery` | HRV, FC reposo, estrés, Body Battery, training readiness |
| `get_fitness_status` | Estado de forma general y predicciones de marca |
| `query_activities_by_date_range` | Actividades entre dos fechas concretas |
| `get_training_load` | Minutos entrenados por semana y ratio ACWR |
| `get_training_recommendation` | Veredicto de "¿qué puedo hacer hoy?" con razones |
| `import_strava_csv` | Importa el `activities.csv` del export de Strava |
| `get_strava_activities` | Actividades importadas de Strava |
| `get_combined_activities` | Garmin + Strava juntas, ordenadas por fecha |
| `get_goal` / `set_goal` | Leer / definir tu meta |
| `get_training_plan` / `save_training_plan` | Leer / guardar el plan |
| `get_adaptation_journal` | Histórico de ajustes al plan |
| `get_exercise_library` | Ejercicios de fuerza/core reales |
| `log_strength_session` | Registra una sesión de gimnasio |
| `get_strength_history` | Histórico de sesiones de fuerza |
| `get_daily_briefing` | Resumen todo-en-uno para decidir el ajuste del día |
## 7. Multi-dispositivo con Supabase (opcional)
Por defecto, el objetivo/plan/diario/histórico se guardan en JSON local.
Si defines `SUPABASE_URL` + `SUPABASE_KEY`, se usa Supabase (Postgres en la nube).
### Crear las tablas en Supabase
En el SQL Editor de tu proyecto Supabase:
```sql
create table if not exists goals (
id int primary key default 1,
sport text,
description text,
target_date date,
details jsonb,
updated_at timestamptz default now()
);
create table if not exists training_plan (
id int primary key default 1,
plan jsonb,
updated_at timestamptz default now()
);
create table if not exists journal (
id bigserial primary key,
ts timestamptz default now(),
note text
);
create table if not exists strength_log (
id bigserial primary key,
date date,
exercises jsonb,
notes text,
logged_at timestamptz default now()
);
```
En Project Settings → API → copia la Project URL y la clave **anon/public**.
### Importar histórico de Strava
1. Strava → Configuración → Mi cuenta → "Descargar o eliminar tu cuenta"
2. Dentro del ZIP: `activities.csv`
3. Dile a Claude: *"Importa mi CSV de Strava, está en /ruta/activities.csv"*
4. Puedes re-importar: las actividades no se duplican
## 8. Notas y límites
- **Librería no oficial**: si Garmin cambia su API, puede dejar de funcionar
hasta que se actualice `garminconnect` (`pip install -U garminconnect`).
- **Sin push/webhooks**: Claude tira de los datos cuando se lo pides; no hay
notificación automática en tiempo real.
- **Los datos de fuerza** dependen de que tu reloj/app los registre con detalle.
- **El motor de recomendación** es un motor de reglas transparente, no un
diagnóstico médico. Si hay dolor o enfermedad, eso pesa más que cualquier número.
### Variables de entorno
| Variable | Requerido | Descripción |
|---|---|---|
| `GARMIN_EMAIL` | Sí | Email de Garmin Connect |
| `GARMIN_PASSWORD` | Sí | Contraseña de Garmin Connect |
| `SUPABASE_URL` | No | URL del proyecto Supabase |
| `SUPABASE_KEY` | No | Clave anon/public de Supabase |
| `MCP_HOST` | No | Host del servidor HTTP (default: `0.0.0.0`) |
| `MCP_PORT` | No | Puerto del servidor HTTP (default: `8080`) |
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing