garmin-local-mcp
Armazém de dados Garmin local-first: sincronize uma vez no SQLite que você possui, depois analise tendências, correlações, linhas de base e anomalias offline, mesmo quando a API da Garmin falhar.
Documentação
garmin-local-mcp
Data warehouse local-first da Garmin com um servidor MCP de nível analítico. Sincronize uma vez, analise para sempre, mesmo quando a API está fora do ar.

Por que outro MCP da Garmin?
Todos os servidores MCP existentes da Garmin seguem o mesmo design: um wrapper fino e ao vivo em torno da API não oficial e limitada da Garmin. Cada pergunta que o assistente de IA faz se torna uma ou mais chamadas de API ao vivo que retornam grandes blocos de JSON bruto (uma única resposta bruta de sono tem cerca de 230 KB). Perguntas de vários meses, como "como meu sono se correlaciona com a carga de treino?", são impraticáveis, e quando a Garmin altera sua autenticação (como fez em março de 2026, quebrando todo o ecossistema), esses servidores ficam completamente inativos, até mesmo para dados que já buscaram ontem.
Este projeto inverte a arquitetura:
- Sincronize uma vez, analise para sempre. Sincronização incremental em um warehouse local: snapshots imutáveis de JSON bruto mais um banco de dados SQLite, em um diretório que você possui.
- Análise no servidor, respostas compactas. Tendências, correlações, linhas de base pessoais e detecção de anomalias são calculadas localmente e retornadas como pequenas tabelas colunares em uma única chamada de ferramenta. Respostas típicas ficam abaixo de 2 KB, então nada inunda o contexto do modelo.
- Resiliência offline. Uma falha na API pausa apenas novas sincronizações. Toda consulta sobre o histórico já sincronizado continua funcionando.
- Um fallback sem autenticação. Um decodificador independente para as mensagens FIT de bem-estar não documentadas da Garmin (pontuação de sono, HRV, temperatura da pele, estágios do sono, cochilos) ingere pacotes exportados manualmente sem nenhum login. Nenhum outro MCP da Garmin oferece isso.
- Ferramentas selecionadas. 12 ferramentas componíveis, não 110.
| garmin-local-mcp | MCPs típicos da Garmin com wrapper de API | |
|---|---|---|
| Armazenamento de dados local que você possui | Sim (JSON bruto + SQLite) | Não |
| Funciona offline após uma falha na API | Sim (análise sobre histórico sincronizado) | Não |
| Análise no servidor (tendências, correlações, linhas de base, anomalias) | Sim | Não (passagem de JSON bruto) |
| Disciplina de tamanho de resposta | Tabelas colunares compactas, tipicamente < 2 KB | Payloads brutos, até centenas de KB |
| Caminho de ingestão sem autenticação | Sim (importação de pacote FIT) | Não |
| Número de ferramentas | 12 selecionadas | Frequentemente 20 a 110+ |
Experimente sem uma conta Garmin
Se você não possui uma Garmin, ou apenas quer ver o que as ferramentas retornam antes de fornecer credenciais, crie um armazenamento sintético:
pip install garmin-local-mcp
garmin-local-mcp --data-dir ~/.garmin-mcp-demo demo
garmin-local-mcp --data-dir ~/.garmin-mcp-demo serve
Isso gera 180 dias em todas as tabelas e as serve via MCP. Sem login, sem rede, sem conta.
Os dados são gerados em vez de registrados, mas não são aleatórios. Um fator de recuperação latente aumenta o HRV enquanto a frequência cardíaca em repouso diminui, a carga de treino eleva a frequência cardíaca em repouso do próximo dia, uma janela de doença de seis dias está no meio do intervalo, e algumas noites de sono estão deliberadamente ausentes. Então as ferramentas de análise têm algo real para encontrar:
| Pergunta | Retorna |
|---|---|
correlate(hrv, resting_hr) | cerca de −0,5, uma relação inversa genuína |
correlate(training_load, resting_hr, scan_lags=True) | ~0 no lag 0, +0,45 no lag 1 — o efeito é no dia seguinte |
anomalies() | a janela de doença, sinalizada em frequência cardíaca em repouso, HRV, temperatura da pele, SpO2 e pontuação de sono ao mesmo tempo |
gaps() | as noites de sono ausentes |
sync_status relata demo_store: true nesses armazenamentos, então um assistente nunca pode apresentar números gerados como medições reais. O gerador é determinístico — --seed reproduz um armazenamento exatamente, e --days altera o intervalo. demo se recusa a sobrescrever um banco de dados que não gerou.
Início rápido
Requer Python 3.12+.
pip install garmin-local-mcp
Ou execute sem instalar, via uv:
uvx garmin-local-mcp --help
1. Faça login uma vez (MFA suportado; tokens persistem localmente, então execuções futuras nunca pedem senha):
garmin-local-mcp login
2. Preencha seu histórico. A sincronização é retomável, segura para interromper e limitada para ser educada com os servidores da Garmin. Um ano de histórico é aproximadamente 1.800 requisições; para preenchimentos longos, inicie e deixe rodar (durante a noite funciona bem). Se for limitada ou interrompida, execute o mesmo comando novamente e ela retoma de onde parou.
garmin-local-mcp sync --from 2026-01-01
3. Registre o servidor MCP no seu cliente (veja Configuração do cliente para Claude Desktop, Cursor e outros clientes):
claude mcp add --scope user garmin -- garmin-local-mcp serve
4. Faça perguntas. Exemplos do que o Claude agora pode responder do seu warehouse local em uma ou duas chamadas de ferramenta:
- "Como minha pontuação de sono se correlaciona com a FC em repouso do dia seguinte?"
- "Quais foram meus dias anômalos de HRV neste trimestre?"
- "Mostre carga de treino semanal vs sono nos últimos 3 meses."
Configuração do cliente
O servidor fala stdio, então qualquer cliente MCP funciona. pip install garmin-local-mcp primeiro (ou use as variantes uvx abaixo, que não precisam de nada instalado além de uv).
Claude Code
claude mcp add --scope user garmin -- garmin-local-mcp serve
Claude Desktop, um clique: baixe garmin-local-mcp-x.y.z.mcpb do último release, então no Claude Desktop abra Configurações > Extensões > Configurações avançadas, clique em "Instalar Extensão…" e selecione o arquivo. Requer uv no seu PATH; a extensão instala e executa o servidor do PyPI via uvx, então nenhuma configuração manual de Python é necessária. Se o diálogo de instalação avisar sobre um Python >=3.12 ausente, você pode ignorar: o uv provisiona seu próprio interpretador.
Claude Desktop, manual (Configurações, depois Desenvolvedor, depois Editar Config; adicione em claude_desktop_config.json):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}
Cursor (~/.cursor/mcp.json, ou .cursor/mcp.json em um projeto):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}
Qualquer outro cliente stdio / sem instalação local (requer uv):
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": ["garmin-local-mcp", "serve"]
}
}
}
Nota: login e o preenchimento inicial sync são etapas de CLI (veja Início rápido); o servidor MCP em si nunca solicita credenciais.
As 12 ferramentas
| Ferramenta | O que faz |
|---|---|
auth_status | Verifica se tokens armazenados do Garmin Connect existem (use antes de sincronizar, ou após um erro de autenticação). |
sync | Busca até 60 dias do Garmin Connect no armazenamento local (padrão: últimos 30 dias terminando ontem; preenchimentos grandes pertencem à CLI). |
sync_status | Cobertura de dados local por tabela, último horário de sincronização e erros de sincronização pendentes. |
get_day | Uma visão mesclada de um único dia: bem-estar, sono, HRV, status de treino, pontuações de desempenho, atividades e sinalizadores de qualidade de dados. |
query_metrics | Série temporal colunar para uma ou mais métricas entre duas datas, com agregação diária/semanal/mensal e estatísticas opcionais. |
correlate | Correlação de Pearson/Spearman entre duas métricas, com suporte a lag de dias e uma varredura opcional sobre lags -7..+7. |
baselines | Banda pessoal de média +/- dp por métrica em uma janela móvel (padrão 28 dias), para julgar o que é normal para este usuário. |
anomalies | Dias de outlier (desvios z-score) e sequências sustentadas (5+ dias consecutivos em um lado da média). |
list_activities | Atividades recentes mais novas primeiro como uma tabela compacta, filtrável por tipo, intervalo de datas e distância mínima. |
get_activity | Linha de resumo completa armazenada para uma atividade (apenas campos de resumo, sem GPS ou fluxos de amostra). |
gaps | Dias ausentes por tabela mais erros de sincronização não resolvidos, para encontrar lacunas que valem re-sincronizar antes de tirar conclusões. |
import_fit | Ingestão offline sem autenticação de um pacote FIT de bem-estar Garmin exportado manualmente. |
Apenas sync e import_fit escrevem algo, e somente dentro do diretório de dados. O servidor nunca solicita: problemas de autenticação retornam como erros estruturados com uma dica apontando para a CLI de login.
Nomes de métricas disponíveis incluem resting_hr, sleep_score, hrv, steps, stress_avg, body_battery_high, skin_temp_dev_c, vo2max, fitness_age, achievable_fitness_age, training_load, endurance_score, hill_score, readiness_score, race_5k_s, e cerca de 35 mais; qualquer ferramenta que receba um nome desconhecido retorna a lista completa.
Pontuações de desempenho
As pontuações periódicas de condicionamento da Garmin ficam em sua própria tabela performance: pontuação de resistência, pontuação de colina (com suas sub-pontuações de resistência e força), prontidão para treino (pontuação, nível, tempo de recuperação) e previsões de corrida para 5k, 10k, meia e maratona completa (todas em segundos).
Elas atualizam no próprio ritmo da Garmin, não diariamente, então performance é deliberadamente excluído de gaps — um dia sem nova pontuação de resistência é normal, não uma lacuna. Previsões de corrida e pontuação de colina só mudam após atividade de corrida qualificada, então longos trechos de nulos são esperados para quem treina principalmente com caminhadas, ciclismo ou musculação.
Layout e propriedade dos dados
Tudo vive em um diretório que você possui (padrão ~/.garmin-mcp, sobrescreva com a variável de ambiente GARMIN_MCP_DATA_DIR ou --data-dir):
~/.garmin-mcp/
├── config.toml # optional settings
├── tokens/ # Garmin Connect session tokens
├── raw/daily/YYYY/YYYY-MM-DD/<endpoint>.json # immutable raw API snapshots
├── raw/activities/<activity_id>.json # one snapshot per activity
└── garmin.db # SQLite warehouse
Os snapshots de JSON bruto são a fonte da verdade e nunca são sobrescritos. O banco de dados SQLite é um índice derivado e reconstruível: garmin-local-mcp reparse o reconstrói dos snapshots brutos inteiramente offline, que é a saída universal para evolução de esquema e correções de parser. Seus dados nunca saem da sua máquina.
Nota de qualidade de dados
Os relógios Garmin reportam uma frequência cardíaca em repouso provisória no dispositivo que pode divergir fortemente do valor finalizado do Garmin Connect em noites com amostragem esparsa. Um caso real observado: o relógio reportou 69 bpm no dispositivo enquanto o Garmin Connect finalizou a mesma noite em 56 bpm.
Este projeto lida com isso de duas maneiras:
- A sincronização da API armazena o valor finalizado do Garmin Connect.
- O importador FIT verifica cruzadamente o valor provisório no dispositivo contra o piso de frequência cardíaca noturno. Uma FC em repouso mais de 10 bpm acima da amostra noturna mais baixa é uma taxa que o relógio nunca observou de fato; ela é sinalizada (
rhr_far_above_hr_floor) e retida, deixando o campo para a API preencher em vez de armazenar um número enganoso.
Registro esparso de estágios do sono é sinalizado da mesma forma (sparse_sleep_stage_logging), e os sinalizadores aparecem em get_day para que a camada de análise saiba quais números confiar.
Runbook offline / fallback
Se a Garmin quebrar a API não oficial novamente (já aconteceu):
- Tudo analítico continua funcionando. Todas as ferramentas de consulta, correlação, linha de base, anomalia e lacunas rodam no seu histórico local já sincronizado. Apenas novas sincronizações pausam.
- Continue ingerindo sem autenticação. Baixe um pacote FIT diário do site do Garmin Connect e importe localmente (passos exatos abaixo).
garmin-local-mcp import-fit <folder>decodifica o pacote com zero autenticação e preenche os dias de lacuna. Linhas originadas de FIT nunca sobrescrevem linhas originadas da API (a menos que você passe--force). - Retome quando a comunidade se atualizar. Acompanhe o projeto python-garminconnect para uma correção, atualize e execute
garmin-local-mcp syncnovamente. Graças ao estado de sincronização retomável, ele retoma exatamente de onde parou.
Baixando um pacote de bem-estar, passo a passo
-
Entre em connect.garmin.com em qualquer navegador.
-
Vá diretamente para https://connect.garmin.com/app/settings/accountInformation (ou clique no seu avatar no canto superior direito, depois Configurações, depois Informações da Conta na barra lateral esquerda).
-
Role até o final da página, até a seção intitulada Exportar Dados de Bem-Estar ("Baixe seus arquivos FIT de bem-estar de um dia específico. Isso inclui dados como passos, sono, estresse, HRV e mais.").
-
Escolha uma data no campo Data e clique em Exportar. Seu navegador baixa um pequeno zip para aquele dia, contendo aproximadamente 12 a 15 arquivos
.fitbinários (*_WELLNESS.fit,*_SLEEP_DATA.fit,*_HRV_STATUS.fit,*_SKIN_TEMP.fit,*_METRICS.fit, e similares). -
Descompacte em uma pasta e execute:
garmin-local-mcp import-fit "path/to/unzipped/folder" -
Repita para cada dia ausente (um pacote por data). A ferramenta
gapsougarmin-local-mcp statusinforma quais dias precisam ser preenchidos.
Duas coisas que vale saber:
- O sono noturno pertence à data do despertar. Para obter o sono da noite passada, exporte a data de ontem se você dormiu até esta manhã, ou seja, a data em que você acordou.
- Esta exportação diária é instantânea e separada da exportação completa da conta
Garmin (o link "Data Management" na mesma página), que é um arquivo em massa
que pode levar dias para chegar por e-mail e não é o que
import-fitespera.
Configuração
config.toml opcional no diretório de dados:
| Chave | Padrão | Significado |
|---|---|---|
timezone | fuso horário do sistema | Nome IANA (ex.: America/Denver) usado para calcular "ontem" para intervalos de sincronização |
units | metric | metric ou statute |
request_delay_seconds | 1.0 | Atraso entre requisições de API durante a sincronização |
baseline_window_days | 28 | Janela padrão de retrospectiva para a ferramenta baselines |
Variáveis de ambiente:
| Variável | Significado |
|---|---|
GARMIN_MCP_DATA_DIR | Substitui o diretório de dados (padrão ~/.garmin-mcp) |
GARMINTOKENS | Substitui o local do armazenamento de tokens (padrão <data_dir>/tokens) |
GARMIN_EMAIL / GARMIN_PASSWORD | Opcional, para re-login não interativo; quando definidas, garmin-local-mcp login pula os prompts (o MFA ainda pode solicitar se sua conta exigir) |
Desenvolvimento
python -m venv .venv
.venv/bin/pip install -e .[dev] # Windows: .venv\Scripts\pip install -e .[dev]
pytest
ruff check .
A suíte de testes roda totalmente offline contra fixtures JSON sanitizadas e pequenas amostras FIT; o CI nunca toca a API ao vivo.
Aviso legal
Este projeto não é afiliado, endossado ou suportado pela Garmin Ltd. Ele usa a biblioteca comunitária python-garminconnect com suas próprias credenciais para acessar seus próprios dados. As APIs da Garmin são não oficiais e podem mudar ou quebrar a qualquer momento; quando isso acontecer, seu histórico sincronizado permanece totalmente utilizável e o caminho de importação FIT continua funcionando.
Todos os dados permanecem na sua máquina. Nada envia dados para fora: sem telemetria, sem serviços de terceiros, sem nuvem. Trate seu diretório de dados como o registro pessoal de saúde que ele é, e nunca o envie para um repositório.
Licença
MIT