Garmin Coach MCP
Provides tools for accessing Garmin Connect data, including recent activities, activity downloads, performance metrics, and per-account settings through a multi-tenant server that authenticates with Garmin credentials.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Garmin Coach MCPshow me my latest running stats"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Garmin Coach MCP
Servidor MCP que conecta Garmin Connect con Claude y ChatGPT. ~95 herramientas, datos en tiempo real, multi-tenant: varias cuentas Garmin en un mismo servidor. · by AlejandrLucena
Qué es, en una frase
Un puente entre tu reloj de muñeca y tu IA: la IA lee tu VFC, Body Battery, sueño, predisposición para entrenar, carga y actividades directamente de tus datos reales de Garmin Connect — con la terminología exacta de Garmin en español.
Sin resúmenes inventados: cada métrica viene de la última sincronización del reloj.
Multi-cuenta: cada persona tiene su propio usuario, su API key y su sesión Garmin.
Sin abrir puertos: tu IA habla con un endpoint HTTPS (
/mcp).
Related MCP server: garmin-mcp
Cómo funciona (3 piezas)
Cuenta Garmin ──► /login (tokens) ──► /data/users/{user}/tokens.json
│
Claude / ChatGPT ──► Conector MCP ──► https://…/mcp (Authorization: Bearer gcm_sk_…)Pieza | Qué es |
API key ( | Nace al crear el usuario. Identifica con quién habla la IA. |
Tokens Garmin | Se generan al conectar la cuenta en |
Conector MCP | En Claude/ChatGPT: URL + cabecera |
Columna «Garmin» del
/admin: Conectado = ese usuario ya guardó sus tokens de Garmin.
Puesta en marcha
1 · Despliega (Dokploy / VPS)
Crea un Servicio Docker Compose en Dokploy apuntando a este repositorio.
Monta un volumen en
/data(guarda usuarios y tokens).Activa HTTPS y apunta tu dominio.
2 · Variables de entorno
Variable | Requerido | Descripción |
| ✔ | Contraseña de |
|
| |
| Tu dominio, ej. | |
|
| |
|
| |
|
| |
|
| |
| Nivel de log ( | |
| URL genérica (JSON) para alertas de sesión Garmin caducada. | |
| Alertas a Telegram (alternativa al webhook genérico). | |
| Deduplicación de alertas (min entre avisos del mismo evento). | |
| Retención de backups automáticos diarios. | |
| Commit a mostrar en |
3 · Da de alta a un usuario (2 minutos)
Abre
https://tudominio.com/admincon tuADMIN_TOKEN.Crear usuario → se genera tu API key al instante.
Copia tu key (se muestra una sola vez), o usa el botón «Enlace de alta»: un enlace único (
/alta/{user}?t=…) que muestra al usuario su key y los pasos para conectar.Conecta su Garmin:
/login, elige al usuario en el desplegable, su email + contraseña + código MFA.
4 · Conecta a Claude
En Claude → Settings → Connectors → Add custom connector:
URL:
https://tudominio.com/mcpRequest headers:
Authorization: Bearer gcm_sk_…(la key del usuario)Autenticación: elige Ninguno (la key va en la cabecera).
Repite por cada cuenta. Un mismo usuario puede usar la misma key en varios dispositivos.
Si usas «Ninguno» sin cabecera, todos los conectores comparten la cuenta global (legacy), no las claves por usuario.
5 · Conecta desde el móvil o la web (OAuth 2.0 + PKCE)
Los conectores de IA que no pueden mandar cabeceras estáticas (Claude móvil/web) usan el flujo OAuth integrado:
Añade el conector apuntando a
https://tudominio.com/mcpsin cabeceras.Al conectar, se abre el navegador → «Autorizar IA»: elige a qué cuenta Garmin vincular y pulsa Permitir.
El conector recibe un token y ya habla con los datos de ese usuario.
Detalles: PKCE obligatorio (S256), tokens de acceso de 1 h con refresh_token rotatorio de 30 días, tokens guardados en hash en /data/oauth_tokens.json. Metadatos de descubrimiento en /.well-known/oauth-protected-resource-metadata.json y /oauth/.well-known/oauth-authorization-server.
Hackeos útiles
¿Con qué cuenta habla mi IA? El panel
/dashboardmuestra la última conexión: «IA conectada · Usuario Juan · hace 2 min».¿Se filtró una key? Regenera desde
/admin: la anterior deja de valer al instante.¿Se filtró un enlace de alta? Botón «Rotar» en
/admin: el enlace antiguo deja de valer y sale uno nuevo.¿Perdiste un usuario o algo se rompió? Export/Import en
/admin: descarga un bundle JSON con claves cifradas y tokens Garmin cifrados, y lo restaura.¿Caducó la sesión Garmin? No debería pasar a menudo: el servidor carga la sesión guardada y la renueva sola vía
di_refresh_token(arreglado: antes no cargaba bien los tokens guardados). Solo cuando Garmin revoca del todo el refresh token hace falta re-conectar en/login(MFA).¿Se te olvida el estado? Configura
TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_ID(oALERT_WEBHOOK_URL) y recibirás un aviso en cuanto una sesión Garmin caduque (deduplicado cadaALERT_MIN_INTERVAL_MINmin).¿Tienes copia de seguridad? Cada día se guarda un snapshot cifrado en
/data/backups/(retenciónBACKUP_KEEP_DAYS, 14 por defecto). Réstáuralo o descárgalo desde la sección «Backups automáticos» de/admin.¿Quieres saber qué commit corre?
/healthexponeversionygit_sha;/admin/statusda el estado por usuario.¿Has tenido actividad sospechosa?
/adminguarda un registro (creaciones, borrados, rotaciones, autorizaciones OAuth…) en un log de actividad acotado.¿Tienes una página bonita de inicio?
/sirve una landing pública; el estado real vive en/dashboard.
Endpoints HTTP
Ruta | Descripción | Acceso |
| Landing pública del proyecto | Público |
| Estado del servidor, versión, git sha y caché | Público |
| Diagnóstico por usuario (tokens OAuth activos, último refresco, errores) | Admin |
| Lista y restaura los backups automáticos diarios | Admin |
| Panel de estado (IA conectada, Garmin, admin) | Admin |
| Filas de estado del panel | Público |
| Gestión de usuarios (crear, ver/regenerar key, enlace de alta, eliminar) | Admin |
| Crea un usuario nuevo (devuelve key + share_token) | Admin |
| Elimina un usuario y sus tokens | Admin |
| Regenera la API key de un usuario | Admin |
| Edita el nombre de un usuario | Admin |
| Rota el | Admin |
| Revoca todos los accesos OAuth de un usuario | Admin |
| Backup / restore completo (users + tokens, cifrados) | Admin |
| Página de alta del usuario (muestra su key + instrucciones) | Enlace secreto |
| Wizard para conectar la cuenta Garmin de un usuario | Admin o API Key |
| Poner / cambiar la contraseña del panel | Admin |
| Actividades recientes (JSON) | Admin o API Key |
| Descarga el .zip/.fit de una actividad | Admin o API Key |
| Config web persistente · ajustes por actividad | Admin o API Key |
| Diagnóstico con datos crudos | Admin o API Key |
| Endpoint MCP principal | Open (red) · OAuth · API Key |
| Servidor OAuth 2.0 + PKCE | Público (flujo OAuth) |
Leyenda: Admin = contraseña
ADMIN_TOKEN(cookie o?token=). Admin o API Key = admin o una keygcm_sk_…por cabecera. OAuth = los conectores móvil/web lo resuelven solos con PKCE./mcpacepta API keys de usuario, tokens OAuth, o la cuenta global legacy; la frontera real es tu red: solo HTTPS y, si quieres, IP/credenciales en Dokploy/Traefik. Todas las respuestas llevan cabeceras de seguridad y rate limiting.
Seguridad
/admin*,/setup/proteccionexigenADMIN_TOKEN.Rutas de datos y login exigen admin o API key válida.
Las API keys nunca se guardan en claro: en disco solo hay SHA-256 + una vista enmascarada (
gcm_sk_…abcd). La key se muestra una sola vez al crearla/regenerarla, y se puede volver a revelar en/alta/{user}solo cuandoADMIN_TOKENestá definido como variable de entorno (si lo rotas, las keys viejas deben regenerarse; la autenticación por hash sigue funcionando).Los tokens de Garmin se guardan cifrados en reposo (
enc:v1:+ XOR con keystream derivado deADMIN_TOKEN, pbkdf2 200k). Límite conocido: los archivos que genera la libreríagarminconnecten su token_dir (por ejemplo/data/legacy/…) quedan en claro; lo cifrado es lo que escribe el servidor.Los tokens OAuth se guardan en hash (SHA-256) en
/data/oauth_tokens.json; elrefresh_tokense rota en cada renovación y el flujo exige PKCE (S256),redirect_urirestringida a localhost o tu propio dominio, y códigos de un solo uso de 10 min. Revócalos desde/admin.REQUIRE_MCP_AUTH=1:/mcpdeja de aceptar la cuenta legacy y exige Bearer válido (API key de usuario o token OAuth) → 401 en el resto. Ideal para cerrar/mcpuna vez que todos tus conectores usan OAuth o cabecera.Sesiones Garmin auto-renovables: el servidor carga los tokens guardados y refresca
di_refresh_tokenautomáticamente (se re-cifran en cada renovación). Cuando ya no es posible, se marca el error y salta la alerta de reconexión.Rate limiting: por IP (30/min login y admin, 180/min
/mcp, 240/min general) y además por usuario en/mcpcuando llevasBearerválido; los 429 incluyenRetry-After.Cabeceras de seguridad (
nosniff,X-Frame-Options: DENY, CSP de referrer, COOP, Permissions-Policy).API key de 48 caracteres aleatorios (
gcm_sk_{32 bytes hex}) + id de usuario aleatorio.Recomendadísimo: define siempre
ADMIN_TOKENfuerte (openssl rand -hex 32).
Instalación local (solo desarrollo)
git clone https://github.com/Alejandrlucena/garmin-coach-mcp.git
cd garmin-coach-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py # → http://localhost:8000Test: pytest tests/
Arquitectura
Claude (PC/móvil) ── Authorization: Bearer gcm_sk_xxx ──► /mcp
│
_UserAuthMiddleware ──► _current_user_id (contextvar)
│
Garmin API client + caché POR USUARIO ──► /data/users/{user_id}/tokens.jsonserver.py: servidor principal — tools MCP + endpoints HTTP + auth multi-tenant + servidor OAuth/PKCE.users.py:UserManager— creación/borrado/regeneración de usuarios y API keys, cifrado de tokens en reposo, backup/restore.index.html: landing pública que se sirve en/.requirements.txt·Dockerfile(con healthcheck) ·docker-compose.yml·.env.example.
Solución de problemas
Síntoma | Causa típica | Arreglo |
Server disconnected al arrancar Claude | Conector configurado como | Usa custom connector por URL ( |
Usuario dice «Sin tokens» | No conectó su Garmin, o se logueó con el usuario equivocado en |
|
Claude funciona pero panel sin usuario | Conector sin cabecera (legacy) | Ponle su |
Key perdida | — |
|
El enlace de alta no muestra la key |
| Pon |
El conector móvil/web no entra por OAuth | El cliente no sigue PKCE, o el flujo se quedó a mitad | Reintenta; usa Claude versión actual. El consentimiento caduca en 10 min |
No entro a |
| Revisa Dokploy variables; |
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Connect your wearables, rings and training apps, then ask your AI about your own health data.
63 tools for Apple Health, Fitbit, Oura & Health Connect data in Claude, ChatGPT, Grok & Mistral.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceExposes Garmin Connect data and workout management to AI agents, supporting tools, resources, and prompts for health data, workout creation, and coaching workflows.1
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to access Garmin Connect activities, workouts, and workout templates for querying and creating workout plans.5MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to query live Garmin Connect health and fitness data, including daily metrics, activities, sleep analysis, and trends via natural language.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/javipaur/garmin-coach-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server