Garmin MCP Server

Conecta-se ao Garmin Connect para expor seus dados de fitness e saúde a clientes compatíveis com MCP.

Documentação

MseeP.ai Security Assessment Badge

Servidor MCP Garmin

Este servidor Model Context Protocol (MCP) conecta-se ao Garmin Connect e expõe seus dados de condicionamento físico e saúde para o Claude e outros clientes compatíveis com MCP.

A API da Garmin é acessada por meio da excelente biblioteca python-garminconnect.

Recursos

  • Listar atividades recentes com suporte a paginação
  • Obter informações detalhadas de atividades
  • Editar atividades: nome, tipo, descrição/notas, tipo de evento, esforço percebido (RPE) e sensação
  • Acessar métricas de saúde (passos, frequência cardíaca, sono, estresse, respiração)
  • Visualizar dados de composição corporal
  • Acompanhar status de treinamento e prontidão
  • Acessar FTP de ciclismo e métricas de limiar de lactato
  • Gerenciar equipamentos e acessórios, incluindo notas de texto livre retornadas por get_gear
  • Acessar treinos e planos de treinamento
  • Inspecionar estruturas detalhadas de etapas de treino, incluindo grupos de repetição e alvos de ritmo de natação
  • Agregados semanais de saúde (passos, estresse, minutos de intensidade)
  • Análises avançadas de ciclismo: zonas de potência, análise de arquivos FIT, inteligência de troca eletrônica DI2
  • Tendência de carga de treinamento (CTL/ATL/TSB), tendência de VFC, tendência de VO2 máx, tendência de frequência respiratória
  • Curva de Duração de Potência, detecção de subidas com VAM, deriva cardíaca (desacoplamento aeróbico), cálculos de W/kg

Cobertura de Ferramentas

Este servidor MCP implementa mais de 110 ferramentas cobrindo ~90% da biblioteca python-garminconnect (v0.3.2):

  • ✅ Gerenciamento de Atividades (20 ferramentas) - inclui ferramentas de escrita para tipo, descrição, tipo de evento, esforço percebido e sensação
  • ✅ Saúde e Bem-Estar (34 ferramentas) - inclui ferramentas personalizadas de resumo leve
  • ✅ Treinamento e Desempenho (13 ferramentas) - inclui tendências de CTL/ATL/TSB, VFC, VO2 máx e respiração
  • ✅ Treinos (8 ferramentas)
  • ✅ Dispositivos (7 ferramentas)
  • ✅ Gerenciamento de Equipamentos (5 ferramentas)
  • ✅ Acompanhamento de Peso (5 ferramentas)
  • ✅ Desafios e Medalhas (10 ferramentas)
  • ✅ Nutrição (9 ferramentas) - registros de alimentos, refeições, alimentos personalizados, registro de alimentos e resumos de ingestão de vários dias
  • ✅ Saúde da Mulher (3 ferramentas)
  • ✅ Perfil do Usuário (3 ferramentas)
  • ✅ Construtores de Treino de Alto Nível (4 ferramentas) - crie e agende treinos sem escrever JSON
  • ✅ Percursos (5 ferramentas) - listar / obter detalhes / enviar GPX como percurso / baixar GPX / excluir percurso
  • ✅ Análise de Atividades (2 ferramentas) - análise de arquivos FIT, Curva de Duração de Potência; requer medidor de potência e/ou Di2
  • ✅ Downloads de Arquivos de Atividade (2 ferramentas) - baixe arquivos de atividade nos formatos FIT, GPX, TCX ou CSV

Nota: As ferramentas de Análise de Atividades requerem um medidor de potência compatível (por exemplo, Garmin Rally, Favero Assioma, PowerTap P1) e/ou troca eletrônica Shimano Di2 / SRAM eTap. A dependência fitparse é instalada automaticamente.

Notas sobre Equipamentos

Cada item no array gear retornado por get_gear inclui um campo notes contendo o valor de Notas em texto livre mostrado no Garmin Connect. Equipamentos sem valor de Notas retornam null; todos os campos existentes de equipamentos permanecem inalterados.

Downloads de Arquivos de Atividade

Duas ferramentas permitem baixar um arquivo de atividade bruto para o disco:

  • download_activity_file(activity_id, format="fit", output_dir=None) — baixa a atividade e a salva no diretório configurado. format aceita fit (padrão), gpx, tcx ou csv.
  • set_fit_download_dir(path) — define e persiste o diretório de download padrão (gravado no arquivo de configuração).

Onde os arquivos são salvos (precedência):

  1. Argumento output_dir — substituição única, não persistida.
  2. Variável de ambiente GARMIN_FIT_DOWNLOAD_DIR.
  3. Configuração persistida definida via set_fit_download_dir.

Comportamento na primeira execução: se nenhum diretório estiver configurado, download_activity_file retorna status: "needs_setup". O assistente perguntará onde você deseja salvar os arquivos (sugerindo o diretório atual como padrão), chamará set_fit_download_dir para persistir sua escolha e, em seguida, tentará o download novamente automaticamente.

Endpoints Intencionalmente Ignorados

Alguns endpoints não são implementados devido a considerações de desempenho ou complexidade:

Alto Volume de Dados:

  • get_activity_details() - Retorna grandes trilhas de GPS e dados de gráficos (50KB-500KB). Use get_activity() para resumos.

Formatos de Treino Especializados:

  • upload_running_workout(), upload_cycling_workout(), upload_swimming_workout() - Envios de treinos específicos de esporte. Use upload_workout() para treinos gerais.

Operações de Manutenção e Destrutivas:

  • delete_activity(), delete_blood_pressure() - Operações destrutivas exigem consideração cuidadosa.
  • Métodos internos/autenticação: login(), resume_login(), connectapi(), download() - Tratados automaticamente pela biblioteca.

Se você precisar de algum desses endpoints, por favor abra uma issue.

Filtragem de Ferramentas

Este servidor registra mais de 110 ferramentas por padrão, o que pode ser muito contexto para um LLM carregar em cada sessão. Você pode expor apenas as ferramentas necessárias com duas variáveis de ambiente opcionais:

Variável de ambienteEfeito
GARMIN_ENABLED_TOOLSLista de permissões separada por vírgulas — se definida, apenas essas ferramentas são registradas.
GARMIN_DISABLED_TOOLSLista de bloqueio separada por vírgulas — as ferramentas listadas são ignoradas. Ignorada se uma lista de permissões for definida.

Os nomes das ferramentas não diferenciam maiúsculas de minúsculas. Com nenhuma variável definida, todas as ferramentas são registradas (comportamento padrão inalterado). Nomes que não correspondem a nenhuma ferramenta são ignorados com um aviso no stderr, o que facilita a identificação de erros de digitação.

Exemplo — exponha apenas sono, estresse e atividades recentes:

"env": {
  "GARMIN_ENABLED_TOOLS": "get_sleep_data,get_stress_summary,get_activities"
}

Ferramentas de treino de alto nível

Essas ferramentas construtoras permitem que um LLM crie e agende treinos sem escrever JSON bruto da Garmin.

create_walk_run_workout

Cria um treino intervalado de caminhada/corrida com alvo opcional de zona de frequência cardíaca.

{
  "name": "W3 Mié 2:2",
  "run_seconds": 120,
  "walk_seconds": 120,
  "repeats": 9,
  "warmup_min": 10,
  "cooldown_min": 8,
  "hr_zone": "Z3"
}

Retorna: {"status": "success", "workout_id": 1234567890, ...}

create_z2_walk_workout

Cria um treino de caminhada constante em Z2.

{
  "name": "Z2 Walk 45m",
  "duration_min": 45,
  "hr_min": 110,
  "hr_max": 130
}

Retorna: {"status": "success", "workout_id": 1234567890, ...}

create_strength_workout

Cria um treino de força a partir de uma lista de exercícios. Cada um se torna uma etapa baseada em repetições, com o nome mantido na descrição da etapa. O nome também é enviado como exerciseName, mas a Garmin só o retém quando corresponde a uma de suas próprias chaves de exercício (por exemplo, FARMERS_CARRY) — qualquer outro valor é aceito e depois armazenado vazio.

category é opcional e passado diretamente. Omita-o e a chave é deixada de fora do payload completamente, o que a Garmin aceita. Forneça-o e deve ser uma das categorias de exercício da Garmin — qualquer outra coisa, incluindo OTHER e UNASSIGNED, é rejeitada com 400 - Invalid category. A lista completa é publicada em 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"}
  ]
}

Retorna: {"status": "success", "workout_id": 1234567890, ...}

schedule_week

Agenda vários treinos em uma única chamada.

{
  "week": [
    {"date": "2026-05-12", "workout_id": 1234567890},
    {"date": "2026-05-14", "workout_id": 1234567891}
  ]
}

Retorna: {"status": "complete", "scheduled": [...]}

Exemplo de fluxo 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

Após sincronizar seu relógio, o treino aparece no calendário do Forerunner 965.

Condições de término brutas do upload_workout

Ao construir JSON de treino personalizado para upload_workout ou upload_workouts, o endCondition.conditionTypeId e o endCondition.conditionTypeKey devem corresponder ao mapeamento canônico da Garmin. A Garmin trata o conditionTypeId numérico como a fonte da verdade; se a chave e o ID entrarem em conflito, a Garmin armazena a condição que corresponde ao ID.

Por exemplo, isso é inválido para uma condição de término de frequência cardíaca porque o ID 4 é calories, não heart.rate:

{
  "endCondition": {
    "conditionTypeId": 4,
    "conditionTypeKey": "heart.rate"
  },
  "endConditionValue": 145
}

Use o ID 6 para frequência cardíaca:

{
  "endCondition": {
    "conditionTypeId": 6,
    "conditionTypeKey": "heart.rate"
  },
  "endConditionValue": 145
}

Para uma condição de término de frequência cardíaca baseada em zona, use endConditionZone (1-5) no mesmo objeto endCondition e omita endConditionValue. Se ambos forem enviados, a Garmin mantém a zona e descarta o valor (verificado contra a API de produção em 2026-09-01):

{
  "endCondition": {
    "conditionTypeId": 6,
    "conditionTypeKey": "heart.rate",
    "endConditionZone": 2
  }
}

IDs comuns de condições de término:

IDChave
1lap.button
2time
3distance
4calories
5power
6heart.rate
7iterations
8fixed.rest
9fixed.repetition
10reps
11training.peaks.tss

Tipos de alvo brutos do upload_workout

Ao construir JSON bruto de treino da Garmin, targetType.workoutTargetTypeId e targetType.workoutTargetTypeKey devem usar o mapeamento canônico da Garmin. A Garmin trata o ID numérico como autoritativo: um payload incompatível como {"workoutTargetTypeId": 6, "workoutTargetTypeKey": "heart.rate"} é armazenado como pace.zone, porque o ID 6 significa pace.zone.

Para uma faixa personalizada de frequência cardíaca, use o tipo de alvo ID 4 com heart.rate.zone e coloque a faixa de bpm em targetValueOne / targetValueTwo. Esses campos de valor pertencem à etapa do treino, juntamente com targetType; não os aninhe dentro do objeto targetType:

{
  "targetType": {
    "workoutTargetTypeId": 4,
    "workoutTargetTypeKey": "heart.rate.zone"
  },
  "targetValueOne": 143,
  "targetValueTwo": 157
}

A mesma forma se aplica a uma faixa personalizada de ritmo de corrida. Os limites de ritmo usam metros por segundo:

{
  "targetType": {
    "workoutTargetTypeId": 6,
    "workoutTargetTypeKey": "pace.zone"
  },
  "targetValueOne": 1.9607843,
  "targetValueTwo": 2.0833333
}

Esse exemplo representa 8:00–8:30 min/km. O limite numérico inferior é listado primeiro para consistência com o exemplo de frequência cardíaca; a Garmin normaliza qualquer ordem de limites. A Garmin descarta silenciosamente valores aninhados dentro de targetType, deixando um alvo de ritmo sem faixa ativa. As ferramentas de envio corrigem esse erro de aninhamento inequívoco, mas rejeitam a solicitação se valores aninhados e de nível de etapa entrarem em conflito.

Para uma zona de FC nomeada da Garmin, use o mesmo tipo de alvo com zoneNumber:

{
  "targetType": {
    "workoutTargetTypeId": 4,
    "workoutTargetTypeKey": "heart.rate.zone"
  },
  "zoneNumber": 3
}

Use zoneNumber ou targetValueOne / targetValueTwo em um alvo, não ambos. A Garmin trata a zona nomeada como autoritativa e descarta silenciosamente uma faixa personalizada coexistente, então as ferramentas de envio rejeitam essa forma ambígua.

Instalação com um clique (Claude Desktop)

A maneira mais fácil de adicionar este servidor ao Claude Desktop é por meio do arquivo de Extensão de Desktop .dxt — sem necessidade de edição de JSON.

Baixar e instalar

  1. Baixe o garmin-mcp.dxt mais recente da página de Releases.
  2. Arraste o arquivo .dxt para a janela do Claude Desktop, ou clique duas vezes nele, ou vá para Configurações → Extensões → Instalar Extensão e selecione o arquivo.
  3. O Claude Desktop solicitará configuração opcional (caminho do token, e-mail, senha).

Autenticação na primeira vez

A extensão instala e executa o servidor automaticamente, mas você deve autenticar com a Garmin uma vez antes que os dados possam ser buscados:

uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth

Isso salva os tokens OAuth em ~/.garminconnect. Depois disso, o servidor funciona sem nenhuma credencial na configuração.

Nota: Os tokens são válidos por aproximadamente 6 meses. Execute novamente garmin-mcp-auth quando eles expirarem.

Compile o .dxt você mesmo

bash scripts/build_dxt.sh   # produces garmin-mcp.dxt in the repo root

Configuração

Início rápido para clientes MCP

A maneira mais fácil de usar este servidor MCP com Claude Desktop, Codex ou outro cliente MCP é autenticar uma vez antes de adicionar o servidor à sua configuração.

Pré-requisitos

  • Python 3.12+
  • Conta Garmin Connect
  • MFA pode ser necessária se estiver habilitada na sua conta

Etapa 1: Pré-autenticação (única vez)

Antes de adicionar o servidor ao seu cliente MCP, autentique-se uma vez no seu 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

Você pode verificar suas credenciais a qualquer momento com

uv run garmin-mcp-auth --verify

Nota: Você também pode definir credenciais por meio de variáveis de ambiente:

GARMIN_EMAIL=your@email.com GARMIN_PASSWORD=secret garmin-mcp-auth

Se você não tiver MFA habilitada, também pode pular garmin-mcp-auth e passar GARMIN_EMAIL e GARMIN_PASSWORD como variáveis de ambiente diretamente para seu cliente MCP, se suportado. Para melhor segurança, prefira o fluxo de pré-autenticação acima e mantenha as credenciais fora da configuração do cliente MCP.

Etapa 2: Configurar o Claude Desktop

Adicione às configurações MCP do seu Claude Desktop SEM credenciais:

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: Nenhum GARMIN_EMAIL ou GARMIN_PASSWORD necessário na configuração! O servidor usa seus tokens salvos.

Etapa 3: Reinicie seu cliente MCP

Seus dados da Garmin agora estão disponíveis para seu cliente MCP.

Para Codex e outros clientes, veja os exemplos abaixo.


Usando mais de uma conta Garmin

Um único processo de servidor está vinculado a uma conta Garmin. Para usar várias contas ao mesmo tempo, execute uma instância do servidor por conta, cada uma com seu próprio diretório de tokens, selecionado com a variável de ambiente GARMINTOKENS. GARMINTOKENS usa como padrão ~/.garminconnect. Aponte para outro local e o servidor lê e grava os tokens lá, deixando o armazenamento padrão intacto.

Etapa 1: Autentique cada conta em seu próprio diretório

garmin-mcp-auth --token-path ~/.garminconnect-alice
garmin-mcp-auth --token-path ~/.garminconnect-bob

--token-path também aceita $GARMINTOKENS, então GARMINTOKENS=~/.garminconnect-alice garmin-mcp-auth é equivalente.

Etapa 2: Declare um servidor por conta

{
  "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 o diretório do qual autentica na inicialização, para que você possa confirmar a configuração:

Trying to login to Garmin Connect using token data from directory '/home/you/.garminconnect-alice'...

Notas

  • Sem fallback silencioso. Se GARMINTOKENS apontar para um diretório sem tokens válidos, a inicialização falha com GarminConnectAuthenticationError em vez de recorrer ao armazenamento padrão. Um segundo servidor mal configurado não pode reutilizar silenciosamente a sessão da primeira conta.

  • ${HOME} é expandido mesmo quando um cliente MCP o passa sem resolução, e ~ funciona no Windows via USERPROFILE.

  • Restrinja ferramentas de escrita em contas secundárias. Ferramentas como upload_workout e schedule_workout gravam na conta à qual o servidor está vinculado. Combine GARMINTOKENS com GARMIN_ENABLED_TOOLS (veja Filtragem de Ferramentas) para tornar uma conta somente leitura:

    "env": {
      "GARMINTOKENS": "${HOME}/.garminconnect-bob",
      "GARMIN_ENABLED_TOOLS": "get_activities,get_activities_by_date,get_activity,get_activity_splits"
    }
    
  • Diretórios de tokens contêm credenciais de longa duração. Eles são criados com permissões somente do proprietário; mantenha-os fora de pastas compartilhadas ou sincronizadas.


Configuração de Desenvolvimento

  1. Instale os pacotes necessários em um novo ambiente:
uv sync

Executando o Servidor

Configuração

Suas credenciais do Garmin Connect são lidas de variáveis de ambiente:

  • GARMIN_EMAIL: Seu endereço de e-mail do Garmin Connect
  • GARMIN_EMAIL_FILE: Caminho para um arquivo contendo seu endereço de e-mail do Garmin Connect
  • GARMIN_PASSWORD: Sua senha do Garmin Connect
  • GARMIN_PASSWORD_FILE: Caminho para um arquivo contendo sua senha do Garmin Connect
  • GARMIN_IS_CN: Defina como true para usar o Garmin Connect China (garmin.cn) em vez da versão internacional (padrão: false)
  • GARMIN_FIT_DOWNLOAD_DIR: Diretório padrão para arquivos de atividades baixados. Quando definido, pula o prompt de configuração da primeira execução em download_activity_file.
  • GARMIN_FIT_CONFIG: Caminho para o arquivo de configuração persistido do diretório de download (padrão: ~/.garminconnect_fit_config.json).

Segredos baseados em arquivos são úteis em certos ambientes, como dentro de um contêiner Docker. Observe que você não pode definir ambos GARMIN_EMAIL e GARMIN_EMAIL_FILE, da mesma forma que não pode definir ambos GARMIN_PASSWORD e GARMIN_PASSWORD_FILE.

Transporte

Por padrão, o servidor se comunica via stdio, que é o que o Claude Desktop, o MCP Inspector e a maioria dos clientes locais esperam. Para servir via HTTP (por exemplo, ao executar em um contêiner ou Kubernetes), defina o transporte por meio de variáveis de ambiente:

  • GARMIN_MCP_TRANSPORT: stdio (padrão), streamable-http ou sse
  • GARMIN_MCP_HOST: endereço de bind para transportes HTTP (padrão 127.0.0.1; defina como 0.0.0.0 somente quando o endpoint estiver atrás de um proxy reverso autenticado)
  • GARMIN_MCP_PORT: porta de bind para transportes HTTP (padrão 8000)
  • GARMIN_MCP_CALL_TIMEOUT: tempo limite por solicitação em segundos para chamadas ao Garmin (padrão 90). A API do Garmin ocasionalmente trava uma única solicitação indefinidamente; sem esse limite, a chamada fica pendurada até que o tempo limite do próprio cliente MCP expire e relate o servidor inteiro como sem resposta. No tempo limite, a ferramenta retorna um erro claro e passível de nova tentativa. Defina como 0 para desabilitar o limite.
GARMIN_MCP_TRANSPORT=streamable-http garmin-mcp

Quando um transporte HTTP é selecionado:

  • Os clientes MCP se conectam ao caminho /mcp (por exemplo, http://localhost:8000/mcp).
  • Um endpoint simples de GET /healthz é exposto para sondagens de liveness/readiness.

O servidor em si não realiza autenticação no endpoint HTTP — coloque-o atrás de um proxy reverso (nginx, Traefik, Authelia, etc.) se ele estiver acessível além do localhost.

Garmin Connect China (garmin.cn)

Se você usa o Garmin Connect China (garmin.cn) em vez da versão internacional, defina a variável de ambiente GARMIN_IS_CN como 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 o Claude Desktop, adicione GARMIN_IS_CN à seção 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, adicione GARMIN_IS_CN=true ao seu arquivo .env ou descomente-o em docker-compose.yml.

Testando o servidor localmente com o MCP Inspector

O Inspector é executado diretamente via npx sem exigir instalação. Execute a partir da raiz do projeto:

npx @modelcontextprotocol/inspector uv run garmin-mcp

Você poderá inspecionar e testar as ferramentas.

Com o Claude Desktop

  1. Crie uma configuração no Claude Desktop:

Edite o arquivo de configuração do Claude Desktop:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Você tem duas opções para executar o MCP localmente com o Claude.

Diretamente do GitHub sem clonar o repositório:

  1. Adicione esta configuração 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"
      }
    }
  }
}

Talvez seja necessário adicionar o caminho completo para uvx; você pode verificar o caminho completo com which uvx

  1. Reinicie o Claude Desktop

Diretamente da sua cópia local do repositório:

  1. Adicione esta configuração de servidor:
{
  "mcpServers": {
    "garmin-local": {
      "command": "uv",
      "args": [
        "--directory",
        "<full path to your local repository>/garmin_mcp",
        "run",
        "garmin-mcp"
      ]
    }
  }
}
  1. Reinicie o Claude Desktop

Com o Codex

O Codex usa TOML para configuração de servidores MCP. Adicione uma das seguintes entradas a ~/.codex/config.toml após autenticar com garmin-mcp-auth.

Você também pode pedir ao seu cliente compatível com MCP para configurar isso para você. Por exemplo:

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.

Diretamente do GitHub sem clonar o repositório

[mcp_servers.garmin]
command = "uvx"
args = [
  "--python",
  "3.12",
  "--from",
  "git+https://github.com/Taxuspt/garmin_mcp",
  "garmin-mcp"
]

Diretamente da sua cópia local do repositório

[mcp_servers.garmin-local]
command = "uv"
args = [
  "--directory",
  "/full/path/to/garmin_mcp",
  "run",
  "garmin-mcp"
]

Reinicie seu cliente MCP após salvar o arquivo.

Com o opencode

opencode carrega automaticamente um opencode.json de nível de projeto quando iniciado a partir da raiz de um repositório, então contribuidores que clonam este repositório obtêm o Garmin MCP conectado ao código-fonte local sem configuração extra.

A partir de um clone deste repositório (recomendado para desenvolvimento)

Este repositório inclui um opencode.json que executa o MCP via uv run garmin-mcp, então ele sempre acompanha a árvore de trabalho.

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

Verifique se o servidor está conectado:

opencode mcp list
# ●  ✓ garmin   connected
#       uv run garmin-mcp

De qualquer outro diretório (instalação via GitHub)

Adicione o servidor à sua configuração global do opencode em ~/.config/opencode/opencode.json após executar 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
    }
  }
}

Reinicie o opencode após salvar o arquivo. A primeira invocação de uvx baixa e armazena em cache o pacote, então a inicialização inicial pode levar alguns segundos.

Com Docker

O Docker fornece um ambiente isolado e consistente para executar o servidor MCP.

Início Rápido com Docker Compose (Recomendado)

  1. Crie um arquivo .env com suas credenciais:
echo "GARMIN_EMAIL=your_email@example.com" > .env
echo "GARMIN_PASSWORD=your_password" >> .env
  1. Inicie o contêiner:
docker compose up -d
  1. Veja os logs para monitorar o servidor:
docker compose logs -f garmin-mcp

Usando Docker Diretamente

# 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 Segredos Baseados em Arquivos (Mais Seguro)

Para maior segurança, especialmente em ambientes de produção, use segredos baseados em arquivos em vez de variáveis de ambiente:

  1. Crie um diretório de segredos e adicione suas credenciais:
mkdir -p secrets
echo "your_email@example.com" > secrets/garmin_email.txt
echo "your_password" > secrets/garmin_password.txt
chmod 600 secrets/*.txt
  1. Edite docker-compose.yml e descomente a seção de segredos:
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
  1. Inicie o contêiner:
docker compose up -d

Lidando com MFA com Docker

Se você tiver autenticação multifator (MFA) habilitada na sua conta Garmin:

  1. Execute o contêiner em modo interativo:
docker compose run --rm garmin-mcp
  1. Quando solicitado, insira seu código MFA:
Garmin Connect MFA required. Please check your email/phone for the code.
Enter MFA code: 123456
  1. Os tokens OAuth serão salvos no volume Docker (garmin-tokens), então você não precisará reautenticar nas execuções subsequentes.

  2. Após a configuração do MFA, você pode executar o contêiner normalmente:

docker compose up -d

Gerenciamento de Volume Docker

Os tokens OAuth são armazenados em um volume Docker persistente para evitar reautenticação:

# 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

Usando com Claude Desktop via Docker

Para usar o servidor MCP em Docker com o Claude Desktop, você pode configurá-lo para se comunicar com o contêiner. No entanto, observe que servidores MCP normalmente se comunicam via stdio, o que funciona melhor com execução direta de processos. Para implantações baseadas em Docker, considere usar o método padrão uvx mostrado na seção Com o Claude Desktop em vez disso.

Exemplos de Uso

Uma vez conectado no Claude, você pode fazer perguntas como:

  • "Mostre minhas atividades recentes"
  • "Como foi meu sono na noite passada?"
  • "Quantos passos dei ontem?"
  • "Mostre os detalhes da minha última corrida"
  • "Analise as zonas de potência do meu último passeio e compare com minhas zonas de treino"
  • "Mostre minha tendência de CTL, ATL e TSB nas últimas 6 semanas"
  • "Qual foi minha curva de duração de potência no passeio de ontem? Estime meu FTP."
  • "Analise os dados FIT da minha última atividade de ciclismo — como foi minha qualidade de troca de marchas nas subidas?"
  • "Mostre minha tendência de HRV nas últimas 2 semanas e sinalize qualquer preocupação de recuperação"
  • "Qual é minha melhor potência de 20 minutos da temporada e quando a estabeleci?"

Solução de Problemas

get_training_effect retorna HTTP 403 para uma atividade válida

O endpoint de detalhes de atividades do Garmin (/activity-service/activity/{id}) pode retornar 403 Forbidden mesmo quando a mesma atividade está visível nas ferramentas de lista. get_training_effect agora recorre à busca na lista de atividades, que ainda inclui efeito de treino aeróbico/anaeróbico para atividades recentes.

Se a atividade for mais antiga que a janela de busca recente, liste a atividade com get_activities / get_activities_by_date e tente novamente, ou use esses campos de lista diretamente.

get_goals não retorna metas que existem no Garmin Connect

O serviço de metas do Garmin só retorna metas criadas na interface atual de Metas do Connect (metas nomeadas de distância/tempo, como uma meta mensal de ciclismo) quando a solicitação envia Sec-Fetch-Site: same-origin e usa um start baseado em 1. Com start=0, ele retorna uma lista vazia. O get_goals() do python-garminconnect não faz ambos (até 0.3.16), então get_goals aqui chama /goal-service/goal/goals diretamente da mesma forma que a página de Metas do Connect faz, e usa a chamada da biblioteca apenas como fallback.

"Falha ao gerar processo: Arquivo ou diretório não encontrado"

Se o Claude Desktop não conseguir encontrar uvx, é porque uvx não está no PATH que o Claude Desktop usa. Para corrigir:

  1. Descubra onde uvx está instalado:
which uvx
  1. Use o caminho completo na sua configuração. Por exemplo, se uvx estiver em /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 bloqueia uv / uvx

No Windows 11 com Smart App Control habilitado, uv.exe / uvx.exe pode ser bloqueado ao iniciar o Garmin_MCP — incluindo quando uv tenta carregar um garmin-mcp.exe não assinado de um .venv local.

Isso não é o mesmo que quarentena do Microsoft Defender Antivirus. O Smart App Control está em:

Segurança do Windows → Controle de aplicativos e navegador → Smart App Control

Sintomas

  • Notificação do Smart App Control ao executar uv, uvx ou Claude Desktop com command: "uvx"
  • O Claude Desktop falha ao gerar o servidor mesmo que uvx pareça instalado
  • Visualizador de Eventos → Logs de Aplicativos e Serviços → Microsoft → Windows → CodeIntegrity → Operacional mostra Erro 3077 do CodeIntegrity mencionando uv.exe e garmin-mcp.exe (política / nível de assinatura Enterprise)

Confirmação

  1. O Smart App Control está Ativado (Avaliação ou Execução).
  2. Verifique o log Operacional do CodeIntegrity para o evento 3077 em torno da falha de inicialização.
  3. O histórico do Defender "Proteção contra vírus e ameaças" pode estar vazio — isso não descarta o SAC.

Recuperações (prefira manter o Smart App Control ativado)

  1. Instale ou reinstale o uv por meio de um canal empacotado e, em seguida, verifique no PowerShell:
    winget install --id=astral-sh.uv -e
    # or: scoop install main/uv
    uvx --version
    
  2. Aponte o Claude Desktop para o caminho completo do uvx.exe (mesma ideia da solução de problemas de PATH acima), por exemplo:
    "command": "C:\\Users\\<you>\\.local\\bin\\uvx.exe"
    
  3. Se o Enforcement ainda bloquear o carregamento do garmin-mcp.exe, talvez seja necessário uma exceção de administrador/política para esse caminho binário. Desativar o Smart App Control globalmente é o último recurso, não a recomendação padrão.
  4. Se o uvx local permanecer bloqueado, use o caminho de instalação via Docker Compose.

Problemas de Login

Se você encontrar problemas de login:

  1. Verifique se suas credenciais estão corretas
  2. Verifique se o Garmin Connect exige verificação adicional
  3. Garanta que o pacote garminconnect esteja atualizado

Logs

Para outros problemas, verifique os logs do Claude Desktop em:

  • macOS: ~/Library/Logs/Claude/mcp-server-garmin.log
  • Windows: %APPDATA%\Claude\logs\mcp-server-garmin.log

Autenticação Multifator (MFA) do Garmin Connect

Entendendo o MFA com Servidores MCP

Os servidores MCP são executados como processos em segundo plano, sem acesso direto ao terminal. Se sua conta Garmin tiver o MFA habilitado, você deve autenticar uma vez usando a ferramenta de pré-autenticação antes que o servidor possa ser executado.

Recomendado: Ferramenta de Pré-Autenticação

A maneira mais fácil de lidar com o MFA é usar a ferramenta de autenticação dedicada:

garmin-mcp-auth

Isso salva os tokens OAuth em ~/.garminconnect para uso futuro. O servidor usará automaticamente esses tokens quando executado no Claude Desktop ou em outros clientes MCP.

Opções Adicionais:

# 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: Primeira Execução Manual

Você também pode autenticar executando o servidor uma vez de forma interativa:

# 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

Após a autenticação inicial, configure o Claude Desktop sem credenciais (os tokens já estão salvos):

{
  "mcpServers": {
    "garmin": {
      "command": "uvx",
      "args": [
        "--python",
        "3.12",
        "--from",
        "git+https://github.com/Taxuspt/garmin_mcp",
        "garmin-mcp"
      ]
    }
  }
}

Usando Docker com MFA

Se estiver usando Docker, siga a seção Handling MFA with Docker acima para uma experiência simplificada com armazenamento persistente de tokens.

Solução de Problemas de MFA

Erro: "MFA authentication required but no interactive terminal available"

Solução:

  1. Abra o terminal
  2. Execute: garmin-mcp-auth
  3. Insira as credenciais e o código MFA
  4. Reinicie o Claude Desktop

Token Expirado

Os tokens OAuth expiram periodicamente (aproximadamente a cada 6 meses). Reautentique:

garmin-mcp-auth --force-reauth

Verifique se os Tokens Funcionam

garmin-mcp-auth --verify

Testes

Este projeto inclui testes abrangentes para todas as ferramentas MCP. Todos os testes estão passando atualmente (100%).

Executando Testes

# 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

Estrutura de Testes

  • Testes de integração (mais de 200 testes): Testam todas as ferramentas MCP usando integração FastMCP com respostas simuladas da API Garmin
  • Testes de ponta a ponta (4 testes): Testam com servidor MCP real e API Garmin (exige credenciais válidas)

Reinstalando a partir do caminho local

Se você estiver trabalhando a partir de um checkout ou fork local:

uv tool install --python 3.12 --force C:\Users\aresd\Desktop\programacion\garmin_mcp