Garmin MCP Server
Se conecta a Garmin Connect para exponer tus datos de fitness y salud a clientes compatibles con MCP.
Documentación
Servidor Garmin MCP
Este servidor del Protocolo de Contexto de Modelos (MCP) se conecta a Garmin Connect y expone tus datos de fitness y salud a Claude y otros clientes compatibles con MCP.
La API de Garmin se accede mediante la excelente biblioteca python-garminconnect.
Características
- Listar actividades recientes con soporte de paginación
- Obtener información detallada de actividades
- Editar actividades: nombre, tipo, descripción/notas, tipo de evento, esfuerzo percibido (RPE) y sensación
- Acceder a métricas de salud (pasos, frecuencia cardíaca, sueño, estrés, respiración)
- Ver datos de composición corporal
- Rastrear estado de entrenamiento y disposición
- Acceder a FTP de ciclismo y métricas de umbral de lactato
- Gestionar equipo y accesorios, incluyendo notas de texto libre devueltas por
get_gear - Acceder a entrenamientos y planes de entrenamiento
- Inspeccionar estructuras detalladas de pasos de entrenamiento, incluidos grupos de repeticiones y objetivos de ritmo de natación
- Agregados semanales de salud (pasos, estrés, minutos de intensidad)
- Análisis avanzados de ciclismo: zonas de potencia, análisis de archivos FIT, inteligencia de cambios electrónicos DI2
- Tendencia de carga de entrenamiento (CTL/ATL/TSB), tendencia de VFC, tendencia de VO2 máx, tendencia de frecuencia respiratoria
- Curva de duración de potencia, detección de ascensos con VAM, deriva cardíaca (desacoplamiento aeróbico), cálculos de W/kg
Cobertura de herramientas
Este servidor MCP implementa más de 110 herramientas que cubren ~90% de la biblioteca python-garminconnect (v0.3.2):
- ✅ Gestión de actividades (20 herramientas) - incluye herramientas de escritura para tipo, descripción, tipo de evento, esfuerzo percibido y sensación
- ✅ Salud y bienestar (34 herramientas) - incluye herramientas personalizadas de resumen ligero
- ✅ Entrenamiento y rendimiento (13 herramientas) - incluye tendencias de CTL/ATL/TSB, VFC, VO2 máx y respiración
- ✅ Entrenamientos (8 herramientas)
- ✅ Dispositivos (7 herramientas)
- ✅ Gestión de equipo (5 herramientas)
- ✅ Seguimiento de peso (5 herramientas)
- ✅ Desafíos e insignias (10 herramientas)
- ✅ Nutrición (9 herramientas) - registros de alimentos, comidas, alimentos personalizados, registro de alimentos y resúmenes de ingesta de varios días
- ✅ Salud de la mujer (3 herramientas)
- ✅ Perfil de usuario (3 herramientas)
- ✅ Constructores de entrenamientos de alto nivel (4 herramientas) - crea y programa entrenamientos sin escribir JSON
- ✅ Cursos (5 herramientas) - listar / obtener detalles / subir GPX como curso / descargar GPX / eliminar curso
- ✅ Análisis de actividad (2 herramientas) - análisis de archivos FIT, curva de duración de potencia; requiere medidor de potencia y/o Di2
- ✅ Descargas de archivos de actividad (2 herramientas) - descarga archivos de actividad en formato FIT, GPX, TCX o CSV
Nota: Las herramientas de análisis de actividad requieren un medidor de potencia compatible (por ejemplo, Garmin Rally, Favero Assioma, PowerTap P1) y/o cambios electrónicos Shimano Di2 / SRAM eTap. La dependencia
fitparsese instala automáticamente.
Notas de equipo
Cada elemento en el array gear devuelto por get_gear incluye un campo notes
que contiene el valor de Notas de texto libre que se muestra en Garmin Connect. El equipo sin
valor de Notas devuelve null; todos los campos existentes de equipo permanecen sin cambios.
Descargas de archivos de actividad
Dos herramientas te permiten descargar un archivo de actividad sin procesar al disco:
download_activity_file(activity_id, format="fit", output_dir=None)— descarga la actividad y la guarda en el directorio configurado.formataceptafit(predeterminado),gpx,tcxocsv.set_fit_download_dir(path)— establece y persiste el directorio de descarga predeterminado (escrito en el archivo de configuración).
Dónde se guardan los archivos (precedencia):
- Argumento
output_dir— anulación única, no persistida. - Variable de entorno
GARMIN_FIT_DOWNLOAD_DIR. - Configuración persistida establecida mediante
set_fit_download_dir.
Comportamiento en el primer uso: si no se configura ningún directorio, download_activity_file devuelve status: "needs_setup". El asistente preguntará dónde quieres guardar los archivos (sugiriendo el directorio actual como predeterminado), llamará a set_fit_download_dir para persistir tu elección y luego reintentará la descarga automáticamente.
Puntos finales omitidos intencionalmente
Algunos puntos finales no se implementan debido a consideraciones de rendimiento o complejidad:
Alto volumen de datos:
get_activity_details()- Devuelve grandes pistas GPS y datos de gráficos (50KB-500KB). Usaget_activity()para resúmenes en su lugar.
Formatos de entrenamiento especializados:
upload_running_workout(),upload_cycling_workout(),upload_swimming_workout()- Cargas de entrenamiento específicas para deportes. Usaupload_workout()para entrenamientos generales.
Operaciones de mantenimiento y destructivas:
delete_activity(),delete_blood_pressure()- Las operaciones destructivas requieren consideración cuidadosa.- Métodos internos/Auth:
login(),resume_login(),connectapi(),download()- Gestionados automáticamente por la biblioteca.
Si necesitas alguno de estos puntos finales, por favor abre un problema.
Filtrado de herramientas
Este servidor registra más de 110 herramientas por defecto, lo que puede ser mucho contexto para que un LLM lo lleve en cada sesión. Puedes exponer solo las herramientas que necesitas con dos variables de entorno opcionales:
| Variable de entorno | Efecto |
|---|---|
GARMIN_ENABLED_TOOLS | Lista de permitidos separada por comas — si se establece, solo se registran estas herramientas. |
GARMIN_DISABLED_TOOLS | Lista de denegados separada por comas — las herramientas listadas se omiten. Se ignora si se establece una lista de permitidos. |
Los nombres de las herramientas no distinguen entre mayúsculas y minúsculas. Con ninguna variable establecida, se registran todas las herramientas (comportamiento predeterminado sin cambios). Los nombres que no coinciden con ninguna herramienta se ignoran con una advertencia en stderr, lo que facilita detectar errores tipográficos.
Ejemplo — exponer solo sueño, estrés y actividades recientes:
"env": {
"GARMIN_ENABLED_TOOLS": "get_sleep_data,get_stress_summary,get_activities"
}
Herramientas de entrenamiento de alto nivel
Estas herramientas constructoras permiten que un LLM cree y programe entrenamientos sin escribir JSON sin procesar de Garmin.
create_walk_run_workout
Crea un entrenamiento de intervalos de caminata/carrera con objetivo opcional de zona de frecuencia cardíaca.
{
"name": "W3 Mié 2:2",
"run_seconds": 120,
"walk_seconds": 120,
"repeats": 9,
"warmup_min": 10,
"cooldown_min": 8,
"hr_zone": "Z3"
}
Devuelve: {"status": "success", "workout_id": 1234567890, ...}
create_z2_walk_workout
Crea un entrenamiento de caminata constante en Z2.
{
"name": "Z2 Walk 45m",
"duration_min": 45,
"hr_min": 110,
"hr_max": 130
}
Devuelve: {"status": "success", "workout_id": 1234567890, ...}
create_strength_workout
Crea un entrenamiento de fuerza a partir de una lista de ejercicios. Cada uno se convierte en un paso basado en repeticiones, con el
nombre mantenido en la descripción del paso. El nombre también se envía como exerciseName, pero Garmin solo
lo retiene cuando coincide con una de sus propias claves de ejercicio (por ejemplo, FARMERS_CARRY) — cualquier otro
valor se acepta y luego se almacena vacío.
category es opcional y se pasa directamente. Omítelo y la clave se deja fuera del
payload por completo, lo que Garmin acepta. Proporciónalo y debe ser una de las categorías de ejercicio de
Garmin — cualquier otra cosa, incluidos OTHER y UNASSIGNED, se rechaza con
400 - Invalid category. La lista completa se publica en
Exercises.json.
{
"name": "Full Body A",
"exercises": [
{"name": "Sentadillas", "sets": 3, "reps": 12, "rest_seconds": 90},
{"name": "Flexiones", "sets": 3, "reps": 15, "rest_seconds": 60},
{"name": "Peso muerto", "sets": 3, "reps": 10, "rest_seconds": 90},
{"name": "Farmers Carry 40m", "sets": 3, "reps": 1, "rest_seconds": 90, "category": "CARRY"}
]
}
Devuelve: {"status": "success", "workout_id": 1234567890, ...}
schedule_week
Programa múltiples entrenamientos en una sola llamada.
{
"week": [
{"date": "2026-05-12", "workout_id": 1234567890},
{"date": "2026-05-14", "workout_id": 1234567891}
]
}
Devuelve: {"status": "complete", "scheduled": [...]}
Ejemplo de flujo completo
create_walk_run_workout(name="W3 Mié 2:2", run_seconds=120, walk_seconds=120,
repeats=9, warmup_min=10, cooldown_min=8)
→ workout_id = 1560092011
schedule_workout(workout_id=1560092011, date="2026-05-06")
→ OK
Después de sincronizar tu reloj, el entrenamiento aparece en el calendario del Forerunner 965.
Condiciones finales sin procesar de upload_workout
Al construir JSON de entrenamiento personalizado para upload_workout o upload_workouts, el
endCondition.conditionTypeId y endCondition.conditionTypeKey deben coincidir con
el mapeo canónico de Garmin. Garmin trata el conditionTypeId numérico como la
fuente de verdad; si la clave y el ID entran en conflicto, Garmin almacena la condición que
coincide con el ID.
Por ejemplo, esto es inválido para una condición final de frecuencia cardíaca porque el ID 4 es
calories, no heart.rate:
{
"endCondition": {
"conditionTypeId": 4,
"conditionTypeKey": "heart.rate"
},
"endConditionValue": 145
}
Usa el ID 6 para frecuencia cardíaca:
{
"endCondition": {
"conditionTypeId": 6,
"conditionTypeKey": "heart.rate"
},
"endConditionValue": 145
}
Para una condición final de frecuencia cardíaca basada en zonas, usa endConditionZone (1-5) en el
mismo objeto endCondition y omite endConditionValue. Si se envían ambos,
Garmin conserva la zona y descarta el valor (verificado contra la API de producción
el 2026-09-01):
{
"endCondition": {
"conditionTypeId": 6,
"conditionTypeKey": "heart.rate",
"endConditionZone": 2
}
}
IDs comunes de condiciones finales:
| ID | Clave |
|---|---|
| 1 | lap.button |
| 2 | time |
| 3 | distance |
| 4 | calories |
| 5 | power |
| 6 | heart.rate |
| 7 | iterations |
| 8 | fixed.rest |
| 9 | fixed.repetition |
| 10 | reps |
| 11 | training.peaks.tss |
Tipos de objetivo sin procesar de upload_workout
Al construir JSON de entrenamiento sin procesar de Garmin, targetType.workoutTargetTypeId y
targetType.workoutTargetTypeKey deben usar el mapeo canónico de Garmin. Garmin
trata el ID numérico como autoritativo: un payload no coincidente como
{"workoutTargetTypeId": 6, "workoutTargetTypeKey": "heart.rate"} se almacena como
pace.zone, porque el ID 6 significa pace.zone.
Para un rango de frecuencia cardíaca personalizado, usa el tipo de objetivo ID 4 con heart.rate.zone y
coloca el rango de bpm en targetValueOne / targetValueTwo. Estos campos de valor
pertenecen al paso del entrenamiento, junto con targetType; no los anides dentro del
objeto targetType:
{
"targetType": {
"workoutTargetTypeId": 4,
"workoutTargetTypeKey": "heart.rate.zone"
},
"targetValueOne": 143,
"targetValueTwo": 157
}
La misma forma se aplica a un rango de ritmo de carrera personalizado. Los límites de ritmo usan metros por segundo:
{
"targetType": {
"workoutTargetTypeId": 6,
"workoutTargetTypeKey": "pace.zone"
},
"targetValueOne": 1.9607843,
"targetValueTwo": 2.0833333
}
Ese ejemplo representa 8:00–8:30 min/km. El límite numérico inferior se lista
primero por consistencia con el ejemplo de frecuencia cardíaca; Garmin normaliza cualquier
orden de límites. Garmin descarta silenciosamente los valores anidados dentro de targetType, dejando
un objetivo de ritmo sin rango activo. Las herramientas de carga reparan ese error de anidación
inequívoco, pero rechazan la solicitud si los valores anidados y a nivel de paso entran en conflicto.
Para una zona de FC nombrada de Garmin, usa el mismo tipo de objetivo con zoneNumber en su lugar:
{
"targetType": {
"workoutTargetTypeId": 4,
"workoutTargetTypeKey": "heart.rate.zone"
},
"zoneNumber": 3
}
Usa ya sea zoneNumber o targetValueOne / targetValueTwo en un objetivo, no
ambos. Garmin trata la zona nombrada como autoritativa y descarta silenciosamente un
rango personalizado coexistente, por lo que las herramientas de carga rechazan esa forma ambigua.
Instalación con un clic (Claude Desktop)
La forma más fácil de agregar este servidor a Claude Desktop es mediante el archivo de Extensión de Escritorio .dxt — sin necesidad de editar JSON.
Descargar e instalar
- Descarga el último
garmin-mcp.dxtdesde la página de Lanzamientos. - Arrastra el archivo
.dxta la ventana de Claude Desktop, o haz doble clic en él, o ve a Configuración → Extensiones → Instalar Extensión y selecciona el archivo. - Claude Desktop te pedirá configuración opcional (ruta del token, correo electrónico, contraseña).
Autenticación por primera vez
La extensión instala y ejecuta el servidor automáticamente, pero debes autenticarte con Garmin una vez antes de que se puedan obtener datos:
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth
Esto guarda los tokens OAuth en ~/.garminconnect. Después de eso, el servidor funciona sin credenciales en la configuración.
Nota: Los tokens son válidos por aproximadamente 6 meses. Vuelve a ejecutar
garmin-mcp-authcuando expiren.
Construye el .dxt tú mismo
bash scripts/build_dxt.sh # produces garmin-mcp.dxt in the repo root
Configuración
Inicio rápido para clientes MCP
La forma más fácil de usar este servidor MCP con Claude Desktop, Codex u otro cliente MCP es autenticarte una vez antes de agregar el servidor a tu configuración.
Requisitos previos
- Python 3.12+
- Cuenta de Garmin Connect
- Puede requerirse MFA si está habilitada en tu cuenta
Paso 1: Pre-autenticación (una sola vez)
Antes de agregar el servidor a tu cliente MCP, autentícate una vez en tu terminal:
# Install and run authentication tool
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth
# You'll be prompted for:
# - Email (or set GARMIN_EMAIL env var)
# - Password (or set GARMIN_PASSWORD env var)
# - MFA code (if enabled on your account)
# OAuth tokens will be saved to ~/.garminconnect
Puedes verificar tus credenciales en cualquier momento con
uv run garmin-mcp-auth --verify
Nota: También puedes establecer credenciales mediante variables de entorno:
GARMIN_EMAIL=your@email.com GARMIN_PASSWORD=secret garmin-mcp-auth
Si no tienes MFA habilitada, también puedes omitir garmin-mcp-auth y pasar GARMIN_EMAIL y GARMIN_PASSWORD como variables de entorno directamente a tu cliente MCP, si es compatible. Para mayor seguridad, prefiere el flujo de pre-autenticación anterior y mantén las credenciales fuera de la configuración del cliente MCP.
Paso 2: Configurar Claude Desktop
Agrega a tu configuración MCP de Claude Desktop SIN credenciales:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
Importante: ¡No se necesitan GARMIN_EMAIL ni GARMIN_PASSWORD en la configuración! El servidor usa tus tokens guardados.
Paso 3: Reinicia tu cliente MCP
Tus datos de Garmin ahora están disponibles para tu cliente MCP.
Para Codex y otros clientes, consulta los ejemplos a continuación.
Usar más de una cuenta de Garmin
Un solo proceso de servidor está vinculado a una cuenta de Garmin. Para usar varias cuentas
a la vez, ejecuta una instancia de servidor por cuenta, cada una con su propio directorio
de tokens, seleccionado con la variable de entorno GARMINTOKENS.
GARMINTOKENS por defecto es ~/.garminconnect. Si lo apuntas a otro lugar, el
servidor lee y escribe tokens allí en su lugar, dejando el almacén predeterminado
intacto.
Paso 1: Autentica cada cuenta en su propio directorio
garmin-mcp-auth --token-path ~/.garminconnect-alice
garmin-mcp-auth --token-path ~/.garminconnect-bob
--token-path también acepta $GARMINTOKENS, por lo que GARMINTOKENS=~/.garminconnect-alice garmin-mcp-auth
es equivalente.
Paso 2: Declara un servidor por cuenta
{
"mcpServers": {
"garmin-alice": {
"command": "uvx",
"args": ["--python", "3.12", "--from", "git+https://github.com/Taxuspt/garmin_mcp", "garmin-mcp"],
"env": {
"GARMINTOKENS": "${HOME}/.garminconnect-alice"
}
},
"garmin-bob": {
"command": "uvx",
"args": ["--python", "3.12", "--from", "git+https://github.com/Taxuspt/garmin_mcp", "garmin-mcp"],
"env": {
"GARMINTOKENS": "${HOME}/.garminconnect-bob"
}
}
}
}
Cada servidor registra el directorio desde el que autentica al iniciarse, para que puedas confirmar la configuración:
Trying to login to Garmin Connect using token data from directory '/home/you/.garminconnect-alice'...
Notas
-
Sin respaldo silencioso. Si
GARMINTOKENSapunta a un directorio sin tokens válidos, el inicio falla conGarminConnectAuthenticationErroren lugar de recurrir al almacén predeterminado. Un segundo servidor mal configurado no puede reutilizar silenciosamente la sesión de la primera cuenta. -
${HOME}se expande incluso cuando un cliente MCP lo pasa sin resolver, y~funciona en Windows medianteUSERPROFILE. -
Restringe las herramientas de escritura en cuentas secundarias. Herramientas como
upload_workoutyschedule_workoutescriben en la cuenta a la que el servidor está vinculado. CombinaGARMINTOKENSconGARMIN_ENABLED_TOOLS(consulta Filtrado de herramientas) para que una cuenta sea de solo lectura:"env": { "GARMINTOKENS": "${HOME}/.garminconnect-bob", "GARMIN_ENABLED_TOOLS": "get_activities,get_activities_by_date,get_activity,get_activity_splits" } -
Los directorios de tokens contienen credenciales de larga duración. Se crean con permisos solo para el propietario; mantenlos fuera de carpetas compartidas o sincronizadas.
Configuración de desarrollo
- Instala los paquetes necesarios en un entorno nuevo:
uv sync
Ejecutar el servidor
Configuración
Tus credenciales de Garmin Connect se leen desde variables de entorno:
GARMIN_EMAIL: Tu dirección de correo de Garmin ConnectGARMIN_EMAIL_FILE: Ruta a un archivo que contiene tu dirección de correo de Garmin ConnectGARMIN_PASSWORD: Tu contraseña de Garmin ConnectGARMIN_PASSWORD_FILE: Ruta a un archivo que contiene tu contraseña de Garmin ConnectGARMIN_IS_CN: Establécelo entruepara usar Garmin Connect China (garmin.cn) en lugar de la versión internacional (predeterminado:false)GARMIN_FIT_DOWNLOAD_DIR: Directorio predeterminado para archivos de actividad descargados. Cuando se establece, omite el aviso de configuración de primera ejecución endownload_activity_file.GARMIN_FIT_CONFIG: Ruta al archivo de configuración persistente del directorio de descargas (predeterminado:~/.garminconnect_fit_config.json).
Los secretos basados en archivos son útiles en ciertos entornos, como dentro de un contenedor Docker. Ten en cuenta que no puedes establecer tanto GARMIN_EMAIL como GARMIN_EMAIL_FILE, de manera similar no puedes establecer tanto GARMIN_PASSWORD como GARMIN_PASSWORD_FILE.
Transporte
Por defecto, el servidor se comunica a través de stdio, que es lo que esperan Claude Desktop, el Inspector MCP y la mayoría de los clientes locales. Para servir a través de HTTP en su lugar (por ejemplo, cuando se ejecuta en un contenedor o Kubernetes), establece el transporte mediante variables de entorno:
GARMIN_MCP_TRANSPORT:stdio(predeterminado),streamable-httposseGARMIN_MCP_HOST: dirección de enlace para transportes HTTP (predeterminado127.0.0.1; establécelo en0.0.0.0solo cuando el endpoint esté protegido por un proxy inverso autenticado)GARMIN_MCP_PORT: puerto de enlace para transportes HTTP (predeterminado8000)GARMIN_MCP_CALL_TIMEOUT: tiempo de espera por solicitud en segundos para llamadas a Garmin (predeterminado90). La API de Garmin ocasionalmente detiene una sola solicitud indefinidamente; sin este límite, la llamada se cuelga hasta que el tiempo de espera del propio cliente MCP se agota y reporta todo el servidor como no receptivo. Al agotarse el tiempo, la herramienta devuelve un error claro y reintentable. Establécelo en0para deshabilitar el límite.
GARMIN_MCP_TRANSPORT=streamable-http garmin-mcp
Cuando se selecciona un transporte HTTP:
- Los clientes MCP se conectan a la ruta
/mcp(por ejemplo,http://localhost:8000/mcp). - Se expone un endpoint
GET /healthzsimple para sondas de actividad/disponibilidad.
El servidor en sí no realiza autenticación en el endpoint HTTP: colócalo detrás de un proxy inverso (nginx, Traefik, Authelia, etc.) si es accesible más allá de localhost.
Garmin Connect China (garmin.cn)
Si usas Garmin Connect China (garmin.cn) en lugar de la versión internacional, establece la variable de entorno GARMIN_IS_CN en true:
# Pre-authenticate with Garmin Connect China
GARMIN_IS_CN=true garmin-mcp-auth
# Or use the CLI flag
garmin-mcp-auth --is-cn
Para Claude Desktop, agrega GARMIN_IS_CN a la sección env:
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"env": {
"GARMIN_IS_CN": "true"
}
}
}
}
Para Docker, agrega GARMIN_IS_CN=true a tu archivo .env o descoméntalo en docker-compose.yml.
Probar el servidor localmente con MCP Inspector
El Inspector se ejecuta directamente a través de npx sin requerir instalación. Ejecuta desde la raíz del proyecto:
npx @modelcontextprotocol/inspector uv run garmin-mcp
Podrás inspeccionar y probar las herramientas.
Con Claude Desktop
- Crea una configuración en Claude Desktop:
Edita tu archivo de configuración de Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Tienes dos opciones para ejecutar el MCP localmente con Claude.
Directamente desde GitHub sin clonar el repositorio:
- Agrega esta configuración de servidor:
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"env": {
"GARMIN_EMAIL": "YOUR_GARMIN_EMAIL",
"GARMIN_PASSWORD": "YOUR_GARMIN_PASSWORD"
}
}
}
}
Es posible que tengas que agregar la ruta completa a uvx; puedes verificar la ruta completa con which uvx
- Reinicia Claude Desktop
Directamente desde tu copia local del repositorio:
- Agrega esta configuración de servidor:
{
"mcpServers": {
"garmin-local": {
"command": "uv",
"args": [
"--directory",
"<full path to your local repository>/garmin_mcp",
"run",
"garmin-mcp"
]
}
}
}
- Reinicia Claude Desktop
Con Codex
Codex usa TOML para la configuración del servidor MCP. Agrega una de las siguientes entradas a ~/.codex/config.toml después de autenticarte con garmin-mcp-auth.
También puedes pedirle a tu cliente compatible con MCP que configure esto por ti. Por ejemplo:
Install the Garmin MCP server from https://github.com/Taxuspt/garmin_mcp, authenticate with garmin-mcp-auth, and add it to my MCP configuration without storing my Garmin email or password.
Directamente desde GitHub sin clonar el repositorio
[mcp_servers.garmin]
command = "uvx"
args = [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
Directamente desde tu copia local del repositorio
[mcp_servers.garmin-local]
command = "uv"
args = [
"--directory",
"/full/path/to/garmin_mcp",
"run",
"garmin-mcp"
]
Reinicia tu cliente MCP después de guardar el archivo.
Con opencode
opencode carga automáticamente un opencode.json a nivel de proyecto cuando se inicia desde la raíz de un repositorio, por lo que los contribuyentes que clonen este repositorio obtienen el Garmin MCP conectado al código fuente local sin configuración adicional.
Desde un clon de este repositorio (recomendado para desarrollo)
Este repositorio incluye un opencode.json que ejecuta el MCP mediante uv run garmin-mcp, por lo que siempre sigue el árbol de trabajo.
git clone https://github.com/Taxuspt/garmin_mcp.git
cd garmin_mcp
uv sync # install dependencies
garmin-mcp-auth # one-time Garmin login (skip if ~/.garminconnect already exists)
opencode # launches with the garmin MCP attached
Verifica que el servidor esté conectado:
opencode mcp list
# ● ✓ garmin connected
# uv run garmin-mcp
Desde cualquier otro directorio (instalación desde GitHub)
Agrega el servidor a tu configuración global de opencode en ~/.config/opencode/opencode.json después de ejecutar garmin-mcp-auth:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"garmin": {
"type": "local",
"command": [
"uvx",
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"enabled": true,
"timeout": 30000
}
}
}
Reinicia opencode después de guardar el archivo. La primera invocación de uvx descarga y almacena en caché el paquete, por lo que el inicio inicial puede tardar unos segundos.
Con Docker
Docker proporciona un entorno aislado y consistente para ejecutar el servidor MCP.
Inicio rápido con Docker Compose (recomendado)
- Crea un archivo
.envcon tus credenciales:
echo "GARMIN_EMAIL=your_email@example.com" > .env
echo "GARMIN_PASSWORD=your_password" >> .env
- Inicia el contenedor:
docker compose up -d
- Consulta los registros para monitorear el servidor:
docker compose logs -f garmin-mcp
Usando Docker directamente
# Build the image
docker build -t garmin-mcp .
# Run the container
docker run -it \
-e GARMIN_EMAIL="your_email@example.com" \
-e GARMIN_PASSWORD="your_password" \
-v garmin-tokens:/root/.garminconnect \
garmin-mcp
Usando secretos basados en archivos (más seguro)
Para mayor seguridad, especialmente en entornos de producción, usa secretos basados en archivos en lugar de variables de entorno:
- Crea un directorio de secretos y agrega tus credenciales:
mkdir -p secrets
echo "your_email@example.com" > secrets/garmin_email.txt
echo "your_password" > secrets/garmin_password.txt
chmod 600 secrets/*.txt
- Edita docker-compose.yml y descomenta la sección de secretos:
services:
garmin-mcp:
environment:
- GARMIN_EMAIL_FILE=/run/secrets/garmin_email
- GARMIN_PASSWORD_FILE=/run/secrets/garmin_password
secrets:
- garmin_email
- garmin_password
secrets:
garmin_email:
file: ./secrets/garmin_email.txt
garmin_password:
file: ./secrets/garmin_password.txt
- Inicia el contenedor:
docker compose up -d
Manejo de MFA con Docker
Si tienes autenticación multifactor (MFA) habilitada en tu cuenta de Garmin:
- Ejecuta el contenedor en modo interactivo:
docker compose run --rm garmin-mcp
- Cuando se te solicite, ingresa tu código MFA:
Garmin Connect MFA required. Please check your email/phone for the code.
Enter MFA code: 123456
-
Los tokens OAuth se guardarán en el volumen de Docker (
garmin-tokens), por lo que no necesitarás volver a autenticarte en ejecuciones posteriores. -
Después de la configuración de MFA, puedes ejecutar el contenedor normalmente:
docker compose up -d
Gestión de volúmenes de Docker
Los tokens OAuth se almacenan en un volumen persistente de Docker para evitar la reautenticación:
# List volumes
docker volume ls
# Inspect the tokens volume
docker volume inspect garmin_mcp_garmin-tokens
# Remove the volume (will require re-authentication)
docker volume rm garmin_mcp_garmin-tokens
Uso con Claude Desktop mediante Docker
Para usar el servidor MCP en Docker con Claude Desktop, puedes configurarlo para que se comunique con el contenedor. Sin embargo, ten en cuenta que los servidores MCP normalmente se comunican a través de stdio, que funciona mejor con la ejecución directa de procesos. Para implementaciones basadas en Docker, considera usar el método estándar uvx que se muestra en la sección Con Claude Desktop en su lugar.
Ejemplos de uso
Una vez conectado en Claude, puedes hacer preguntas como:
- "Muéstrame mis actividades recientes"
- "¿Cómo fue mi sueño anoche?"
- "¿Cuántos pasos di ayer?"
- "Muéstrame los detalles de mi última carrera"
- "Analiza las zonas de potencia de mi último recorrido y compáralas con mis zonas de entrenamiento"
- "Muéstrame la tendencia de mi CTL, ATL y TSB de las últimas 6 semanas"
- "¿Cuál fue mi curva de duración de potencia del recorrido de ayer? Estima mi FTP."
- "Analiza los datos FIT de mi última actividad de ciclismo: ¿cómo fue mi calidad de cambios en las subidas?"
- "Muéstrame la tendencia de mi VFC de las últimas 2 semanas y señala cualquier preocupación de recuperación"
- "¿Cuál es mi mejor potencia de 20 minutos de la temporada y cuándo la establecí?"
Solución de problemas
get_training_effect devuelve HTTP 403 para una actividad válida
El endpoint de detalles de actividad de Garmin (/activity-service/activity/{id}) puede
devolver 403 Prohibido incluso cuando la misma actividad es visible en las herramientas de lista.
get_training_effect ahora recurre a la búsqueda de la lista de actividades, que aún
incluye el efecto de entrenamiento aeróbico/anaeróbico para actividades recientes.
Si la actividad es más antigua que la ventana de búsqueda reciente, lista la actividad con
get_activities / get_activities_by_date y reintenta, o usa esos campos de lista
directamente.
get_goals no devuelve objetivos que existen en Garmin Connect
El servicio de objetivos de Garmin solo devuelve objetivos creados en la interfaz de objetivos actual de Connect
(objetivos de distancia/tiempo con nombre, como un objetivo mensual de ciclismo) cuando la solicitud
envía Sec-Fetch-Site: same-origin y usa un start basado en 1. Con
start=0, devuelve una lista vacía. El get_goals() de python-garminconnect no hace ambas cosas
(hasta 0.3.16), por lo que get_goals aquí llama a /goal-service/goal/goals
directamente de la misma manera que lo hace la página de objetivos de Connect, y usa la llamada de la biblioteca solo como
respaldo.
"Error al iniciar el proceso: No existe el archivo o directorio"
Si Claude Desktop no puede encontrar uvx, es porque uvx no está en el PATH que usa Claude Desktop. Para solucionarlo:
- Encuentra dónde está instalado
uvx:
which uvx
- Usa la ruta completa en tu configuración. Por ejemplo, si
uvxestá en/Users/username/.cargo/bin/uvx:
{
"mcpServers": {
"garmin": {
"command": "/Users/username/.cargo/bin/uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
Windows: Smart App Control bloquea uv / uvx
En Windows 11 con Smart App Control habilitado, uv.exe / uvx.exe pueden estar bloqueados al iniciar Garmin_MCP, incluido cuando uv intenta cargar un garmin-mcp.exe sin firmar desde un .venv local.
Esto no es lo mismo que la cuarentena de Microsoft Defender Antivirus. Smart App Control está en:
Seguridad de Windows → Control de aplicaciones y navegador → Smart App Control
Síntomas
- Notificación de Smart App Control al ejecutar
uv,uvxo Claude Desktop concommand: "uvx" - Claude Desktop no puede iniciar el servidor incluso cuando
uvxparece estar instalado - Visor de eventos → Registros de aplicaciones y servicios → Microsoft → Windows → CodeIntegrity → Operativo muestra Error de CodeIntegrity 3077 que menciona
uv.exeygarmin-mcp.exe(nivel de firma de política / Enterprise)
Confirmación
- Smart App Control está Activado (Evaluación o Aplicación).
- Revisa el registro operativo de CodeIntegrity para el evento 3077 alrededor del inicio fallido.
- El historial de "Protección contra virus y amenazas" de Defender puede estar vacío; eso no descarta SAC.
Recuperaciones (se recomienda mantener Smart App Control activado)
- Instale o reinstale
uva través de un canal empaquetado, luego verifique en PowerShell:winget install --id=astral-sh.uv -e # or: scoop install main/uv uvx --version - Apunte Claude Desktop a la ruta completa de
uvx.exe(misma idea que la solución de problemas de PATH anterior), por ejemplo:"command": "C:\\Users\\<you>\\.local\\bin\\uvx.exe" - Si Enforcement aún bloquea la carga de
garmin-mcp.exe, es posible que necesite una excepción de administrador/política para esa ruta binaria. Desactivar Smart App Control globalmente es un último recurso, no el consejo predeterminado. - Si uvx local sigue bloqueado, use la ruta de instalación de Docker Compose en su lugar.
Problemas de inicio de sesión
Si encuentra problemas de inicio de sesión:
- Verifique que sus credenciales sean correctas
- Compruebe si Garmin Connect requiere verificación adicional
- Asegúrese de que el paquete garminconnect esté actualizado
Registros
Para otros problemas, revise los registros de Claude Desktop en:
- macOS:
~/Library/Logs/Claude/mcp-server-garmin.log - Windows:
%APPDATA%\Claude\logs\mcp-server-garmin.log
Autenticación multifactor de Garmin Connect (MFA)
Comprensión de MFA con servidores MCP
Los servidores MCP se ejecutan como procesos en segundo plano sin acceso directo a la terminal. Si su cuenta de Garmin tiene MFA habilitado, debe autenticarse una vez usando la herramienta de preautenticación antes de que el servidor pueda ejecutarse.
Recomendado: Herramienta de preautenticación
La forma más fácil de manejar MFA es usando la herramienta de autenticación dedicada:
garmin-mcp-auth
Esto guarda los tokens OAuth en ~/.garminconnect para uso futuro. El servidor usará automáticamente estos tokens cuando se ejecute en Claude Desktop u otros clientes MCP.
Opciones adicionales:
# Use environment variables for credentials
GARMIN_EMAIL=you@example.com GARMIN_PASSWORD=secret garmin-mcp-auth
# Verify existing tokens
garmin-mcp-auth --verify
# Force re-authentication (e.g., when tokens expire)
garmin-mcp-auth --force-reauth
# Use custom token location
garmin-mcp-auth --token-path ~/.garmin_tokens
Alternativa: Primera ejecución manual
También puede autenticarse ejecutando el servidor una vez de forma interactiva:
# Store credentials in files for security
echo "your_email@example.com" > ~/.garmin_email
echo "your_password" > ~/.garmin_password
chmod 600 ~/.garmin_email ~/.garmin_password
# Run server interactively to authenticate
GARMIN_EMAIL_FILE=~/.garmin_email GARMIN_PASSWORD_FILE=~/.garmin_password \
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp
# Enter MFA code when prompted
# Tokens will be saved automatically
# Now add to Claude Desktop config without credentials
Después de la autenticación inicial, configure Claude Desktop sin credenciales (los tokens ya están guardados):
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
Uso de Docker con MFA
Si usa Docker, siga la sección Manejo de MFA con Docker anterior para una experiencia optimizada con almacenamiento persistente de tokens.
Solución de problemas de MFA
Error: "Se requiere autenticación MFA pero no hay terminal interactiva disponible"
Solución:
- Abra la terminal
- Ejecute:
garmin-mcp-auth - Ingrese las credenciales y el código MFA
- Reinicie Claude Desktop
Token caducado
Los tokens OAuth caducan periódicamente (aproximadamente cada 6 meses). Vuelva a autenticarse:
garmin-mcp-auth --force-reauth
Verificar que los tokens funcionen
garmin-mcp-auth --verify
Pruebas
Este proyecto incluye pruebas exhaustivas para todas las herramientas MCP. Todas las pruebas están pasando actualmente (100%).
Ejecución de pruebas
# Run all integration tests (default - uses mocked Garmin API)
uv run pytest tests/integration/
# Run tests with verbose output
uv run pytest tests/integration/ -v
# Run a specific test module
uv run pytest tests/integration/test_health_wellness_tools.py -v
# Run end-to-end tests (requires real Garmin credentials)
uv run pytest tests/e2e/ -m e2e -v
Estructura de pruebas
- Pruebas de integración (más de 200 pruebas): Prueban todas las herramientas MCP usando integración FastMCP con respuestas simuladas de la API de Garmin
- Pruebas de extremo a extremo (4 pruebas): Prueban con el servidor MCP real y la API de Garmin (requiere credenciales válidas)
Reinstalación desde ruta local
Si está trabajando desde un checkout o fork local:
uv tool install --python 3.12 --force C:\Users\aresd\Desktop\programacion\garmin_mcp
