garmin_mcp
CLAUDE.md1.4k starsChanged 20 days agoMITView on GitHub
This is a Model Context Protocol (MCP) server that connects to Garmin Connect and exposes fitness and health data to Claude and other MCP-compatible clients. The server provides 122 tools organized into 15 functional modules. The integration with Garmin's API is done via the python-garminconnect library. ALWAYS reference the python-garminconnect repository and these two files: These files are your source of truth for: - Available API endpoints - Check if a method actually exists in the library - Correct method…
We split this CLAUDE.md into the rules it gives an agent
16 rules. About 0 are common, 13 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 19
Available API endpoints: - Check if a method actually exists in the library
- Distinctive: line 20
Correct method signatures: - Verify parameter names and types
- Distinctive: line 30
Not all Garmin Connect API endpoints have corresponding methods in python-garminconnect.
- Distinctive: line 33
Search the library source code
- Distinctive: line 35
If a method doesn't exist in python-garminconnect, you'll need to either:
- Distinctive: line 36
Use an alternative method that provides similar data
- Very specific: line 138
Check python-garminconnect first: Verify the method exists in example.py or demo.py
- Distinctive: line 140
Choose the correct module: Add the tool to the appropriate module based on functionality
- Very specific: line 160
Add tests: Create integration tests in tests/integration/test_[module]_tools.py
- Distinctive: line 173
224 integration tests: - Test all MCP tools with mocked Garmin API
- Distinctive: line 183
9 end-to-end tests: - Test with real MCP server and Garmin API (requires credentials)
- Distinctive: line 192
Success case: Verify the tool works with expected data
- Distinctive: line 193
Exception case: Verify error handling when the API fails
- Very specific: line 264
All tools return str (MCP requirement).
- Distinctive: line 272
If the method you're trying to use isn't documented there, it likely doesn't exist in the library.
- Distinctive: line 276
Check the example files to see what the actual API returns.
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Garmin MCP Server - Project Guide
Overview
This is a Model Context Protocol (MCP) server that connects to Garmin Connect and exposes fitness and health data to Claude and other MCP-compatible clients. The server provides 122 tools organized into 15 functional modules.
Critical: Garmin API Integration
The integration with Garmin's API is done via the python-garminconnect library.
When Debugging or Implementing New Tools
ALWAYS reference the python-garminconnect repository and these two files:
- example.py - Contains examples for many available API endpoints
- demo.py - Comprehensive demo with 100+ API methods organized by category
These files are your source of truth for:
- Available API endpoints - Check if a method actually exists in the library
- Correct method signatures - Verify parameter names and types
- Expected output formats - See what data structure each endpoint returns
- Method names - Confirm the exact name of Garmin client methods
Library Version
Currently using: garminconnect==0.3.2 (see pyproject.toml)
Important Note
Not all Garmin Connect API endpoints have corresponding methods in python-garminconnect. Before implementing a new tool:
- Check example.py
- Check demo.py
- Search the library source code
If a method doesn't exist in python-garminconnect, you'll need to either:
- Use an alternative method that provides similar data
- Request the feature in the python-garminconnect repository
- Implement a custom API call if absolutely necessary
Project Structure
src/garmin_mcp/
├── __init__.py # Main MCP server entry point
├── __main__.py # Module entry point
├── activity_analysis.py # Activity analysis and FIT file parsing
├── activity_management.py # Activity CRUD operations
├── auth_cli.py # Pre-authentication CLI (garmin-mcp-auth)
├── challenges.py # Challenges and badges
├── courses.py # Course management
├── data_management.py # Data upload/download operations
├── devices.py # Device information
├── gear_management.py # Gear tracking
├── health_wellness.py # Health metrics (steps, HR, sleep, etc.)
├── nutrition.py # Nutrition and food logging
├── token_utils.py # OAuth token management utilities
├── training.py # Training and performance metrics
├── user_profile.py # User account information
├── weight_management.py # Weight and body composition
├── womens_health.py # Women's health tracking
├── workout_builders.py # Programmatic workout creation
├── workout_templates.py # Workout template helpers
└── workouts.py # Workout management
tests/
├── integration/ # 224 tests with mocked Garmin API
│ ├── test_activity_analysis_tools.py
│ ├── test_activity_management_tools.py
│ ├── test_challenges_tools.py
│ ├── test_health_wellness_tools.py
│ ├── test_nutrition_tools.py
│ ├── test_other_modules_tools.py
│ ├── test_training_tools.py
│ ├── test_workout_builders_tools.py
│ └── test_workouts_tools.py
└── e2e/ # 9 end-to-end tests (require real credentials)
└── test_server_e2e.pyArchitecture
Module Pattern
Each functional module follows this pattern:
# Global client reference (set by main)
garmin_client = None
def configure(client):
"""Configure the module with the Garmin client instance"""
global garmin_client
garmin_client = client
def register_tools(app):
"""Register all tools with the MCP server app"""
@app.tool()
async def tool_name(param: str) -> str:
"""Tool description"""
try:
result = garmin_client.method_name(param)
if not result:
return f"No data found."
return result
except Exception as e:
return f"Error: {str(e)}"
return appMain Server (init.py)
The main server:
- Initializes the Garmin Connect client
- Configures all modules with the client instance
- Registers all tools from each module
- Handles authentication (including MFA)
Authentication
Garmin credentials are read from environment variables:
GARMIN_EMAILorGARMIN_EMAIL_FILEGARMIN_PASSWORDorGARMIN_PASSWORD_FILE
For accounts with MFA enabled, use the pre-authentication CLI before starting the MCP server:
garmin-mcp-authThis saves OAuth tokens to ~/.garminconnect so the MCP server can start without an interactive terminal. Token utilities are in token_utils.py.
Development Guidelines
Adding a New Tool
- Check python-garminconnect first: Verify the method exists in example.py or demo.py
- Choose the correct module: Add the tool to the appropriate module based on functionality
- Follow the pattern:
@app.tool() async def get_something(param: str) -> str: """Clear description of what the tool does Args: param: Description of parameter """ try: result = garmin_client.garminconnect_method(param) if not result: return f"No data found." return result except Exception as e: return f"Error: {str(e)}" - Add tests: Create integration tests in
tests/integration/test_[module]_tools.py
Error Handling
All tools should:
- Wrap API calls in try/except blocks
- Return user-friendly error messages
- Handle empty/null responses gracefully
Testing
The project has comprehensive test coverage:
224 integration tests - Test all MCP tools with mocked Garmin API
# Run all integration tests
uv run pytest tests/integration/ -v
# Run specific module tests
uv run pytest tests/integration/test_health_wellness_tools.py -v9 end-to-end tests - Test with real MCP server and Garmin API (requires credentials)
uv run pytest tests/e2e/ -m e2e -vTest Structure
Each tool should have at least two tests:
- Success case: Verify the tool works with expected data
- Exception case: Verify error handling when the API fails
Example:
async def test_tool_success(app_with_module, mock_garmin_client):
"""Test tool with valid response"""
mock_garmin_client.method.return_value = {"data": "value"}
result = await call_tool(app_with_module, "tool_name", {"param": "value"})
assert "value" in result
async def test_tool_exception(app_with_module, mock_garmin_client):
"""Test tool when API raises exception"""
mock_garmin_client.method.side_effect = Exception("API Error")
result = await call_tool(app_with_module, "tool_name", {"param": "value"})
assert "Error" in resultRunning the Server
With MCP Inspector (for testing)
npx @modelcontextprotocol/inspector uv run garmin-mcpWith Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"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"
}
}
}
}Common Patterns
Date Parameters
Many tools accept dates in YYYY-MM-DD format:
async def get_data(date: str) -> str:
"""Get data for a specific date
Args:
date: Date in YYYY-MM-DD format
"""Activity IDs
Activity IDs are typically large integers (e.g., 12345678901):
async def get_activity_detail(activity_id: int) -> str:Return Types
All tools return str (MCP requirement). Complex objects are returned as JSON strings.
Troubleshooting
Method doesn't exist in garminconnect
Always check example.py and demo.py first!
If the method you're trying to use isn't documented there, it likely doesn't exist in the library.
Unexpected output format
Check the example files to see what the actual API returns. The Garmin API can return different structures than expected.
Authentication issues
For MFA accounts, run garmin-mcp-auth first to pre-authenticate and save tokens.
Check logs at:
- macOS:
~/Library/Logs/Claude/mcp-server-garmin.log - Windows:
%APPDATA%\Claude\logs\mcp-server-garmin.log
Key Dependencies
garminconnect==0.3.2- Garmin Connect API wrappermcp>=1.23.0- Model Context Protocol SDKfitparse>=1.2.0- FIT file parsing for activity analysispython-dotenv==1.2.2- Environment variable managementrequests==2.33.0- HTTP client
Resources
Trending
Less talk lately.thin dataabout the whole repository
Who's talking about Taxuspt/garmin_mcp
- fedetic/garmin-coach-plugin“Upstream update available: garmin_mcp / garminconnect”GitHub · Oct 26, 2026
- dbhq-uk/garmin-skill“fix(data): parse nested training status and use captured fixtures”GitHub · Sep 24, 2026
- cyberjunky/python-garminconnect“get_goals() returns empty results for goals visible in current Garmin Connect UI”GitHub · Sep 13, 2026
- dharmendra-gupta/garmin_mcp“Backlog: update README and fix release/packaging chores for the fork”GitHub · Aug 25, 2026
- wouterrodeyns/garmin_mcp“Fix Garmin cycling power target encoding”GitHub · Aug 11, 2026
The biggest 5 of 11 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 11
Talked about on GitHub (11 times).
On GitHub · 11
- Oct 26, 2026Upstream update available: garmin_mcp / garminconnect — fedetic/garmin-coach-plugin0 reactions
- Sep 24, 2026fix(data): parse nested training status and use captured fixtures — dbhq-uk/garmin-skill0 reactions · 1 comment
- Sep 13, 2026get_goals() returns empty results for goals visible in current Garmin Connect UI — cyberjunky/python-garminconnect0 reactions · 5 comments
- Aug 25, 2026Backlog: update README and fix release/packaging chores for the fork — dharmendra-gupta/garmin_mcp0 reactions
- Aug 11, 2026Fix Garmin cycling power target encoding — wouterrodeyns/garmin_mcp0 reactions
6 more on GitHub
- Aug 8, 2026Add Garmin MCP server (Taxuspt) project config — Caires7/Caires70 reactions
- Jul 14, 2026garmin-mcp-auth executable name collides with Taxuspt/garmin_mcp — breaks side-by-side installation — brunosantos/garmin-workouts-mcp0 reactions
- Jul 6, 2026Set up Garmin MCP server and wrapper — lukeabela38/Personal-Trainer0 reactions · 1 comment
- Apr 14, 2026fix: address PR #77 review — gustavclausen/garmin_mcp0 reactions
- Mar 31, 2026Wrong values used when creating workouts with `create-workout` — mlindgren/garmin-connect-mcp0 reactions · 2 comments
- Mar 30, 2026Feature request: reading and managing scheduled workouts — etweisberg/garmin-connect-mcp0 reactions · 2 comments
In this repositoryOne other file it gives its agents.
- babysit-prsSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

