
Garmy – AI-powered Python library for accessing and analyzing your Garmin health by bes-dev
An AI-powered Python library for Garmin Connect API designed specifically for health data analysis and AI agent integration via Model Context Protocol (MCP). Build intelligent health assistants and data analysis tools with seamless access to Garmin’s comprehensive fitness metrics.
Inspired by garth – This project was heavily inspired by the excellent garth library, building upon its foundation with enhanced modularity, type safety, and AI integration capabilities.
- 🤖 AI-First Design: Built specifically for AI health agents and intelligent assistants
- 🔌 MCP Integration: Native Model Context Protocol support for seamless AI interactions
- 🏥 Health Analytics: Advanced data analysis capabilities for fitness and wellness insights
- 📊 Rich Metrics: Complete access to sleep, heart rate, stress, training readiness, and more
- 🗣️ Natural Language: Query health data using conversational commands
- ⚡ Real-time Processing: Async/await support for high-performance AI applications
- 🛡️ Type Safe: Full type hints and runtime validation for reliable AI workflows
- 🔄 Auto-Discovery: Automatic metric registration and API endpoint discovery
git clone https://github.com/bes-dev/garmy.git cd garmy pip install -e ".[dev,mcp]"
from garmy import AuthClient, APIClient import asyncio # Create an AI health agent async def health_agent(): auth_client = AuthClient() api_client = APIClient(auth_client=auth_client) # Login using environment variables (secure for AI agents) await auth_client.login_async( email=os.getenv('GARMIN_EMAIL'), password=os.getenv('GARMIN_PASSWORD') ) # AI agent can now analyze multiple health metrics concurrently sleep_task = api_client.metrics.get('sleep').get_async() readiness_task = api_client.metrics.get('training_readiness').get_async() hrv_task = api_client.metrics.get('hrv').get_async() sleep_data, readiness_data, hrv_data = await asyncio.gather( sleep_task, readiness_task, hrv_task ) # AI analysis logic here health_score = analyze_health_trends(sleep_data, readiness_data, hrv_data) return health_score # Run AI health agent health_insights = asyncio.run(health_agent())
from garmy import AuthClient, APIClient # Create clients auth_client = AuthClient() api_client = APIClient(auth_client=auth_client) # Login auth_client.login("your_email@garmin.com", "your_password") # Get today's training readiness readiness = api_client.metrics.get('training_readiness').get() print(f"Training Readiness Score: {readiness[0].score}/100") # Get sleep data for specific date sleep_data = api_client.metrics.get('sleep').get('2023-12-01') print(f"Sleep Score: {sleep_data[0].overall_sleep_score}") # Get multiple days of data weekly_steps = api_client.metrics['steps'].list(days=7)
import asyncio from garmy import AuthClient, APIClient async def main(): auth_client = AuthClient() api_client = APIClient(auth_client=auth_client) # Login await auth_client.login_async("your_email@garmin.com", "your_password") # Get multiple metrics concurrently sleep_task = api_client.metrics.get('sleep').get_async() hr_task = api_client.metrics.get('heart_rate').get_async() sleep_data, hr_data = await asyncio.gather(sleep_task, hr_task) asyncio.run(main())
Garmy provides access to a comprehensive set of Garmin Connect metrics:
Metric | Description | Example Usage |
---|---|---|
sleep |
Sleep tracking data including stages and scores | api_client.metrics.get('sleep').get() |
heart_rate |
Daily heart rate statistics | api_client.metrics.get('heart_rate').get() |
stress |
Stress level measurements | api_client.metrics.get('stress').get() |
steps |
Daily step counts and goals | api_client.metrics.get('steps').list(days=7) |
training_readiness |
Training readiness scores and factors | api_client.metrics.get('training_readiness').get() |
body_battery |
Body battery energy levels | api_client.metrics.get('body_battery').get() |
hrv |
Heart rate variability data | api_client.metrics.get('hrv').get() |
respiration |
Respiration rate measurements | api_client.metrics.get('respiration').get() |
calories |
Daily calorie burn data | api_client.metrics.get('calories').get() |
activities |
Activity summaries and details | api_client.metrics.get('activities').list(days=30) |
daily_summary |
Comprehensive daily health summary | api_client.metrics.get('daily_summary').get() |
Garmy is specifically designed for building AI health agents and intelligent assistants through native Model Context Protocol (MCP) integration. Transform your Garmin health data into actionable insights using natural language interactions.
Garmy isn’t just an API wrapper – it’s a complete AI health agent platform that enables:
- 🧠 Intelligent Health Analysis: AI-powered insights into sleep patterns, training readiness, and recovery
- 🗣️ Natural Language Queries: Ask questions like “How was my sleep quality this week?” or “Am I ready for training today?”
- 📊 Predictive Analytics: Build AI models that predict optimal training times, recovery needs, and health trends
- 🔄 Real-time Monitoring: Create AI agents that continuously monitor health metrics and provide recommendations
- 🎨 Custom Health Dashboards: Generate AI-driven visualizations and reports tailored to individual health goals
- 📱 Multi-modal Integration: Combine Garmin data with other health sources for comprehensive AI analysis
# Install Garmy with MCP support pip install garmy[mcp] # Verify installation garmy-mcp --help
# Start MCP server for Claude Desktop (STDIO transport) garmy-mcp serve --transport stdio # Start HTTP server for web clients garmy-mcp serve --transport http --port 8080 # Show server information garmy-mcp info # List available metrics garmy-mcp metrics # Test server configuration garmy-mcp test
from garmy.mcp import GarmyMCPServer, MCPConfig # Create and configure server config = MCPConfig.for_production() server = GarmyMCPServer(config) # Run server server.run(transport="stdio") # For Claude Desktop server.run(transport="http", port=8080) # For HTTP clients
Add this to your Claude Desktop MCP configuration file:
{ "mcpServers": { "garmy": { "command": "/path/to/your/venv/bin/python", "args": ["-m", "garmy.mcp", "serve", "--transport", "stdio"], "env": { "GARMIN_EMAIL": "your_email@example.com", "GARMIN_PASSWORD": "your_password", "GARMY_MCP_DEBUG": "false", "GARMY_MCP_CACHE_ENABLED": "true" } } } }
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%Claudeclaude_desktop_config.json
- Linux:
~/.config/Claude/claude_desktop_config.json
Garmy MCP supports multiple authentication methods:
export GARMIN_EMAIL="your_email@example.com" export GARMIN_PASSWORD="your_password"
- ✅ Credentials never pass through AI servers
- ✅ Most secure method
- ✅ Use with: “Auto-login to Garmin Connect”
⚠️ Credentials may be visible to AI servers⚠️ Use only when necessary⚠️ Use with: “Log into Garmin Connect with email [email] and password [password]”
Once configured, your AI health agent can interact with Garmin data using natural language. Here are examples of what your AI assistant can do:
- “Analyze my recovery patterns and tell me if I should train today”
- “What’s my sleep efficiency trend over the past month?”
- “Create a personalized training plan based on my readiness scores”
- “Identify correlations between my stress and sleep quality”
- “Generate a health report with actionable insights”
- “Predict my optimal training windows for next week”
- “What factors are affecting my sleep quality most?”
- “Alert me when my recovery metrics indicate overtraining”
- “Build a model to predict my daily energy levels”
- “How am I progressing towards my fitness goals?”
- “What’s unusual about my health data this week?”
- “Compare my current training load to last month”
- “Should I adjust my sleep schedule based on my data?”
- “Create an interactive dashboard of my health metrics”
- “Export my data in a format suitable for machine learning”
- “Generate a health summary for my doctor”
- “Build charts showing my progress over time”
Variable | Description | Default |
---|---|---|
GARMIN_EMAIL |
Garmin Connect email | None |
GARMIN_PASSWORD |
Garmin Connect password | None |
GARMY_MCP_DEBUG |
Enable debug logging | false |
GARMY_MCP_CACHE_ENABLED |
Enable data caching | false |
GARMY_MCP_CACHE_SIZE |
Cache size limit | 100 |
GARMY_MCP_MAX_HISTORY_DAYS |
Max historical data | 365 |
GARMY_MCP_DEFAULT_ANALYSIS_PERIOD |
Default analysis period | 30 |
from garmy.mcp.config import MCPConfig # Development setup config = MCPConfig.for_development() # Production setup config = MCPConfig.for_production() # Minimal setup config = MCPConfig.minimal()
-
“Server not responding”
# Check if server is running garmy-mcp test # Restart with debug mode GARMY_MCP_DEBUG=true garmy-mcp serve --transport stdio
-
“Authentication failed”
# Verify credentials echo $GARMIN_EMAIL echo $GARMIN_PASSWORD # Test authentication garmy-mcp test --auth
-
“No data available”
# Check available metrics garmy-mcp metrics # Verify date range garmy-mcp test --date 2023-12-01
Enable debug logging for troubleshooting:
# Enable debug mode export GARMY_MCP_DEBUG=true # Run server with debug output garmy-mcp serve --transport stdio --debug
75 else ‘recovery’,
‘confidence’: model.score(X_test, y_test)
}
‘confidence’: model.score(X_test, y_test)
}
return insights” dir=”auto”>
from garmy import APIClient, AuthClient import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.preprocessing import StandardScaler # Setup AI health analysis pipeline auth_client = AuthClient() api_client = APIClient(auth_client=auth_client) auth_client.login("email", "password") # Gather comprehensive health data for AI model async def build_health_dataset(days=90): # Collect multiple health metrics concurrently tasks = [ api_client.metrics.get('sleep').list_async(days=days), api_client.metrics.get('training_readiness').list_async(days=days), api_client.metrics.get('hrv').list_async(days=days), api_client.metrics.get('stress').list_async(days=days), api_client.metrics.get('body_battery').list_async(days=days) ] sleep_data, readiness_data, hrv_data, stress_data, battery_data = await asyncio.gather(*tasks) # Build comprehensive health dataset health_df = pd.DataFrame() # ... merge and process data for AI model training return health_df # Train AI model to predict training readiness def train_readiness_predictor(health_df): features = ['sleep_score', 'hrv_rmssd', 'stress_avg', 'body_battery_drained'] X = health_df[features] y = health_df['training_readiness_score'] model = RandomForestRegressor(n_estimators=100, random_state=42) model.fit(X, y) return model # AI-powered health insights def generate_health_insights(model, current_metrics): predicted_readiness = model.predict([current_metrics])[0] insights = { 'readiness_prediction': predicted_readiness, 'recommendation': 'high_intensity' if predicted_readiness > 75 else 'recovery', 'confidence': model.score(X_test, y_test) } return insights
80:
return “Great day for high-intensity training!”
elif health_score > 60:
return “Moderate activity recommended. Focus on technique.”
else:
return “Prioritize recovery today. Light movement only.”
return “Great day for high-intensity training!”
elif health_score > 60:
return “Moderate activity recommended. Focus on technique.”
else:
return “Prioritize recovery today. Light movement only.”
async def weekly_health_report(self):
“””Generate comprehensive AI health report”””
week_data = await self.api_client.metrics.get(‘daily_summary’).list_async(days=7)
# AI trend analysis
trends = self.analyze_trends(week_data)
predictions = self.predict_next_week(week_data)
return self.format_health_report(trends, predictions)
# Usage
agent = HealthMonitoringAgent(api_client)
daily_insights = await agent.daily_health_check()
weekly_report = await agent.weekly_health_report()” dir=”auto”>
# Create an AI health monitoring agent class HealthMonitoringAgent: def __init__(self, api_client): self.api_client = api_client self.health_model = self.load_trained_model() async def daily_health_check(self): """Perform daily AI-powered health analysis""" # Get today's metrics today_data = await self.get_current_metrics() # AI analysis health_score = self.health_model.predict_health_score(today_data) recommendations = self.generate_recommendations(health_score, today_data) alerts = self.check_health_alerts(today_data) return { 'health_score': health_score, 'recommendations': recommendations, 'alerts': alerts, 'insights': self.generate_insights(today_data) } def generate_recommendations(self, health_score, data): """AI-generated personalized health recommendations""" if health_score > 80: return "Great day for high-intensity training!" elif health_score > 60: return "Moderate activity recommended. Focus on technique." else: return "Prioritize recovery today. Light movement only." async def weekly_health_report(self): """Generate comprehensive AI health report""" week_data = await self.api_client.metrics.get('daily_summary').list_async(days=7) # AI trend analysis trends = self.analyze_trends(week_data) predictions = self.predict_next_week(week_data) return self.format_health_report(trends, predictions) # Usage agent = HealthMonitoringAgent(api_client) daily_insights = await agent.daily_health_check() weekly_report = await agent.weekly_health_report()
Check out the examples/
directory for comprehensive usage examples:
# Basic authentication example python examples/basic_auth.py # Sleep analysis demo python examples/sleep_demo.py # Training readiness analysis python examples/training_readiness_demo.py # Comprehensive metrics sync python examples/metrics_sync_demo.py # MCP server demo python examples/mcp_integration_demo.py
Garmy’s modular architecture makes it easy to add new metrics:
bool:
“””Custom validation logic”””
return self.custom_field > 0″ dir=”auto”>
“””Custom validation logic”””
return self.custom_field > 0″ dir=”auto”>
from dataclasses import dataclass from garmy.core.base import BaseMetric @dataclass class CustomMetric(BaseMetric): endpoint_path = "/usersummary-service/stats/custom/{date}" custom_field: int timestamp: str def validate(self) -> bool: """Custom validation logic""" return self.custom_field > 0
Customize Garmy behavior with configuration:
from garmy.core.config import set_config, GarmyConfig # Create custom configuration config = GarmyConfig( request_timeout=30, retries=3, max_workers=10, default_user_agent="MyApp/1.0" ) # Apply configuration set_config(config) # Or use environment variables import os os.environ['GARMY_REQUEST_TIMEOUT'] = '30' os.environ['GARMY_MAX_WORKERS'] = '10'
# Install development dependencies make install-dev # Run all tests make test # Run specific test modules make test-core # Core functionality make test-auth # Authentication make test-metrics # Metrics make test-mcp # MCP server # Check code quality make lint make quick-check
import asyncio from garmy import APIClient, AuthClient async def analyze_weekly_data(): auth_client = AuthClient() api_client = APIClient(auth_client=auth_client) # Async login await auth_client.login_async("email", "password") # Fetch multiple metrics concurrently tasks = [ api_client.metrics.get('sleep').list_async(days=7), api_client.metrics.get('steps').list_async(days=7), api_client.metrics.get('stress').list_async(days=7) ] sleep_data, steps_data, stress_data = await asyncio.gather(*tasks) return { 'sleep': sleep_data, 'steps': steps_data, 'stress': stress_data } # Run async analysis data = asyncio.run(analyze_weekly_data())
from garmy.core.exceptions import APIError, AuthError, GarmyError try: auth_client.login("wrong_email", "wrong_password") except AuthError as e: print(f"Authentication failed: {e}") except APIError as e: print(f"API error: {e}") except GarmyError as e: print(f"General Garmy error: {e}")
from garmy.core.config import set_config, GarmyConfig # Configure retry behavior
1 Comment
bes-dev
We're living in this crazy time where MCP lets us connect more data to AI than ever before – and honestly, it's game-changing for understanding ourselves.
But here's what's been bugging me: Garmin makes these incredible sensors that track literally everything about your body, yet their analytics feel like they're stuck in 2010. You get basic charts and generic insights that tell you nothing useful.
Like, my sleep was trash last night – but WHY? Training readiness is low – but what's the actual connection to what happened yesterday?
So I built Garmy – an open-source Python library that pulls all your Garmin data and connects it to AI through MCP. Now I can actually have conversations with my health data.
Real examples from using it:
– Going to bed after 2am drops my next day's training readiness by 15-20 points (who knew!)
– As a solo entrepreneur, I was coding late + training hard during the day – classic burnout recipe. AI spotted the pattern between my sleep quality, workout recovery, and stress levels way before I felt completely fried. Now I have actual data-driven boundaries instead of just "I'll sleep when I'm dead"
– Stress of all-night coding kills my sleep quality through HRV and REM – Claude found that connection, not me!
– Export data to my coach, now they see the full picture instead of just activities
The AI conversations are natural:
"What's messing with my sleep?"
"Should I train hard today or am I pushing too much?"
"Why has my recovery been garbage for three days?"
Instead of staring at charts trying to connect dots, I just… ask. And get real answers that actually help me not burn out.
Links:
GitHub: https://github.com/bes-dev/garmy
Who else wanted better analytics from their Garmin data? Curious what you'll discover!