Skip to main content
Glama
epodivilov

garmin-connect-mcp

by epodivilov
README.md
# Garmin Connect MCP Server

A Model Context Protocol (MCP) server that provides comprehensive access to Garmin Connect data including sleep analytics, health metrics, activities, and training volume analysis. Perfect for building AI-powered fitness insights, training analysis, and health tracking applications.

## Table of Contents

- [Overview](#overview)
- [Features](#features)
- [Setup](#setup)
- [Available Tools](#available-tools)
- [Usage Examples](#usage-examples)
- [Advanced Features](#advanced-features)
- [Development](#development)
- [Security](#security)

## Overview

This MCP server connects your AI assistant (Claude Desktop, Claude Code, or any MCP-compatible client) directly to your Garmin Connect account, enabling:

- **Real-time Health Insights**: Access sleep, heart rate, steps, stress, and body battery data
- **Training Analytics**: Aggregate training volume by week, month, or custom date ranges
- **Activity Analysis**: Retrieve detailed activity data with filtering and pagination
- **Multi-metric Summaries**: Get comprehensive daily health overviews

**Tech Stack**: TypeScript, Node.js 20+, MCP SDK, garmin-connect library

## Features

### šŸŒ™ Sleep Analytics
- Detailed sleep stages (deep, light, REM, awake)
- Sleep scores and quality metrics
- Duration and timing analysis
- Summary and detailed modes

### šŸ’Ŗ Health Metrics
- **Steps**: Daily step counts, goals, and progress tracking
- **Heart Rate**: Resting HR, max HR, zones, and time-series data
- **Body Composition**: Weight tracking and body composition
- **Stress & Recovery**: Stress levels and body battery metrics

### šŸƒ Activity Tracking
- Recent activity lists with filtering
- Detailed activity information (splits, laps, metrics)
- Activity-specific data (distance, duration, pace, elevation)
- Pagination support for large datasets

### šŸ“Š Training Volume Analysis
- Weekly training aggregation (ISO week standards)
- Monthly training summaries
- Custom date range analysis (up to 365 days)
- Activity type filtering (running, cycling, swimming, etc.)
- Trend analysis (week-over-week, month-over-month)
- Sport-specific breakdowns

## Setup

### Prerequisites

1. **Garmin Connect Account**: Active account with data from a compatible Garmin device
2. **Node.js**: Version 20 or higher
3. **MCP Client**: Claude Desktop, Claude Code, or another MCP-compatible application

### Installation

#### Option 1: Use with npx (Recommended)

No installation required! Configure directly in your MCP client:

**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows):

```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "npx",
      "args": ["-y", "garmin-connect-mcp@latest"],
      "env": {
        "GARMIN_USERNAME": "your_username",
        "GARMIN_PASSWORD": "your_password"
      }
    }
  }
}
```

**Claude Code**:

Using the Claude Code CLI (recommended):
```bash
claude mcp add garmin-connect npx garmin-connect-mcp@latest \
  --env GARMIN_USERNAME=your_username \
  --env GARMIN_PASSWORD=your_password
```

Or manually configure (`.claude/mcp.json` in your project):
```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "npx",
      "args": ["-y", "garmin-connect-mcp@latest"],
      "env": {
        "GARMIN_USERNAME": "your_username",
        "GARMIN_PASSWORD": "your_password"
      }
    }
  }
}
```

The `-y` flag automatically accepts the npx prompt, ensuring smooth startup.

#### Option 2: Global Installation

Install globally via npm:

```bash
npm install -g garmin-connect-mcp@latest
```

Then configure without npx:

```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "garmin-connect-mcp",
      "env": {
        "GARMIN_USERNAME": "your_username",
        "GARMIN_PASSWORD": "your_password"
      }
    }
  }
}
```

#### Option 3: Local Development

For development or testing local changes:

```bash
git clone <repository-url>
cd garmin-connect-mcp
pnpm install
pnpm build
```

Configure with absolute path:

```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "node",
      "args": ["/absolute/path/to/garmin-connect-mcp/dist/index.js"],
      "env": {
        "GARMIN_USERNAME": "your_username",
        "GARMIN_PASSWORD": "your_password"
      }
    }
  }
}
```

Or use a `.env` file:

```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "node",
      "args": ["/absolute/path/to/garmin-connect-mcp/dist/index.js"],
      "envFile": "/absolute/path/to/garmin-connect-mcp/.env"
    }
  }
}
```

## Available Tools

### Overview Tools

#### `get_daily_overview`
Get a comprehensive daily summary including sleep, activities, and health metrics in one call.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)

**Example:**
```
Show me my daily overview for yesterday
```

**Response includes:**
- Sleep summary (duration, quality, stages)
- Activity summary (count, total duration, distance)
- Health metrics (steps, heart rate, stress, body battery)

---

### Sleep Tools

#### `get_sleep_data`
Get detailed sleep information including sleep stages, movements, and quality metrics.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)
- `summary` (optional): Return only summary data (default: false)
- `fields` (optional): Specific fields to include (e.g., `['dailySleepDTO', 'wellnessEpochSummaryDTO']`)

**Example:**
```
Get my detailed sleep data for 2025-01-15
Show me a sleep summary for last night
```

**Response includes:**
- Total sleep duration
- Sleep stages (deep, light, REM, awake) with durations
- Sleep scores and quality ratings
- Start/end times
- Movement data (when `summary: false`)

#### `get_sleep_duration`
Quick access to total sleep duration for a specific date.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)

**Example:**
```
How many hours did I sleep last night?
```

---

### Health Metrics Tools

#### `get_health_metrics`
Get aggregated health metrics for a specific date.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)
- `metrics` (optional): Array of specific metrics `['steps', 'weight', 'heart_rate', 'stress', 'body_battery']` (defaults to all)

**Example:**
```
What are my health metrics for today?
Show me just my steps and heart rate for yesterday
```

**Response includes:**
- Steps data (count, goal, distance)
- Heart rate (resting, max, zones)
- Stress levels
- Body battery percentage
- Weight and body composition

#### `get_steps_data`
Get detailed step count and activity data.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)
- `summary` (optional): Return only summary data (default: false)

**Example:**
```
Show me my step data for today
How many steps did I take yesterday?
```

**Response includes:**
- Total steps
- Daily goal and progress percentage
- Distance covered
- Active time
- Hourly breakdown (when `summary: false`)

#### `get_heart_rate_data`
Get detailed heart rate measurements and zone data.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)
- `summary` (optional): Return only summary data (default: false)

**Example:**
```
What was my heart rate today?
Show me my heart rate zones for yesterday
```

**Response includes:**
- Resting heart rate
- Maximum heart rate
- Average heart rate
- Heart rate zones and time in each zone
- Time-series measurements (when `summary: false`)

#### `get_weight_data`
Get weight and body composition data.

**Parameters:**
- `date` (optional): Date in `YYYY-MM-DD` format (defaults to today)

**Example:**
```
What's my current weight?
Show me my weight for last week
```

**Response includes:**
- Weight (kg/lbs)
- BMI
- Body fat percentage
- Muscle mass
- Body water percentage

---

### Activity Tools

#### `get_activities`
Get a list of recent activities with optional filtering and pagination.

**Parameters:**
- `start` (optional): Starting index for pagination (default: 0)
- `limit` (optional): Number of activities to return, max 50 (default: 20)
- `summary` (optional): Return compact summary format (default: false)

**Example:**
```
List my last 10 activities
Show me my recent runs
Get activities 20-40 (for pagination)
```

**Response includes:**
- Activity ID and name
- Activity type (running, cycling, swimming, etc.)
- Start time and duration
- Distance, pace, speed
- Calories and elevation gain
- Heart rate data
- Splits and laps (when `summary: false`)

#### `get_activity_details`
Get comprehensive information for a specific activity.

**Parameters:**
- `activityId` (required): The unique ID of the activity

**Example:**
```
Show me details for activity 12345678
Give me the full breakdown of my last run
```

**Response includes:**
- Complete activity metadata
- Detailed splits and laps
- Heart rate zones
- Cadence, power, and other sensor data
- GPS/route information
- Weather conditions

---

### Training Volume Tools

#### `get_weekly_volume`
Get aggregated training volume for a specific ISO week.

**Parameters:**
- `year` (optional): Year (defaults to current year)
- `week` (optional): ISO week number 1-53 (defaults to current week)
- `includeActivityBreakdown` (optional): Include per-sport breakdown (default: true)
- `includeTrends` (optional): Compare with previous week (default: false)
- `maxActivities` (optional): Max activities to process, up to 2000 (default: 1000)
- `activityTypes` (optional): Filter by activity types (e.g., `['running', 'cycling']`)

**Example:**
```
What was my training volume this week?
Show me week 42 of 2024 with trends
Compare my running volume this week vs last week
```

**Response includes:**
- Week number and date range
- Total metrics (duration, distance, calories, elevation)
- Activity count
- Breakdown by activity type
- Week-over-week trends (when `includeTrends: true`)

#### `get_monthly_volume`
Get aggregated training volume for a specific month.

**Parameters:**
- `year` (optional): Year (defaults to current year)
- `month` (optional): Month number 1-12 (defaults to current month)
- `includeActivityBreakdown` (optional): Include per-sport breakdown (default: true)
- `includeTrends` (optional): Compare with previous month (default: false)
- `maxActivities` (optional): Max activities to process, up to 2000 (default: 1000)
- `activityTypes` (optional): Filter by activity types

**Example:**
```
What was my training volume in January?
Show me this month's cycling volume
Compare my training this month vs last month
```

**Response includes:**
- Month name and date range
- Total metrics (duration, distance, calories, elevation)
- Activity count
- Breakdown by activity type
- Month-over-month trends

#### `get_custom_range_volume`
Get training volume for any custom date range (up to 365 days).

**Parameters:**
- `dateRange` (required): Date range as `YYYY-MM-DD/YYYY-MM-DD`
- `includeActivityBreakdown` (optional): Include per-sport breakdown (default: true)
- `includeDailyBreakdown` (optional): Include day-by-day breakdown (default: false)
- `maxActivities` (optional): Max activities to process, up to 2000 (default: 1000)
- `activityTypes` (optional): Filter by activity types

**Example:**
```
What was my training volume from 2025-01-01 to 2025-01-31?
Show me my running volume for the last 90 days
Give me a daily breakdown for the past 2 weeks
```

**Response includes:**
- Date range and period length
- Total metrics across the range
- Activity count
- Breakdown by activity type
- Daily breakdown (when `includeDailyBreakdown: true`)

## Usage Examples

### Quick Health Check
```
What's my daily overview for today?
```

### Sleep Analysis
```
Show me my sleep quality for the past week
Compare my deep sleep from Monday vs Tuesday
```

### Training Insights
```
How much did I run this month?
Compare my weekly volume: this week vs last week
What's my total training time for Q1 2025?
```

### Activity Exploration
```
List my last 20 activities
Show me all my runs from January with heart rate data
What was my fastest 5K in the past 6 months?
```

### Advanced Queries
```
Get my weekly running volume with trends for week 15 of 2025
Show me daily breakdown of cycling for 2025-03-01/2025-03-31
What are my health metrics (just steps and heart rate) for yesterday?
```

## Advanced Features

### Pagination
For large activity lists, use pagination:
```javascript
// Get activities 0-49
get_activities({ start: 0, limit: 50 })

// Get activities 50-99
get_activities({ start: 50, limit: 50 })
```

### Activity Type Filtering
Filter training volume by specific sports:
```javascript
get_weekly_volume({
  activityTypes: ['running', 'cycling'],
  includeTrends: true
})
```

### Trend Analysis
Compare periods to track progress:
```javascript
// Week-over-week comparison
get_weekly_volume({ includeTrends: true })

// Month-over-month comparison
get_monthly_volume({ includeTrends: true })
```

### Summary vs Detailed Modes
Control response size and detail level:
```javascript
// Quick summary
get_sleep_data({ summary: true })

// Full detailed breakdown with time-series
get_sleep_data({ summary: false })
```

### Response Size Management
The server automatically validates response sizes and provides fallback summaries if data exceeds limits. For large date ranges, consider:
- Using `summary: true` mode
- Filtering by specific activity types
- Reducing date ranges
- Disabling detailed breakdowns

## Development

### Commands

```bash
# Development
pnpm install          # Install dependencies
pnpm build            # Build for production
pnpm dev              # Watch mode with auto-rebuild

# Quality Checks
pnpm typecheck        # Run TypeScript type checking
pnpm lint             # Lint code
pnpm lint:fix         # Auto-fix linting issues

# Testing
pnpm test             # Run tests in watch mode
pnpm test:run         # Run tests once
pnpm test:coverage    # Generate coverage report
```

### Project Structure

```
garmin-connect-mcp/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ client/           # Garmin Connect API client
│   ā”œā”€ā”€ tools/            # MCP tool implementations
│   │   ā”œā”€ā”€ overview-tools.ts
│   │   ā”œā”€ā”€ sleep-tools.ts
│   │   ā”œā”€ā”€ health-tools.ts
│   │   ā”œā”€ā”€ activity-tools.ts
│   │   └── activity-volume-tools.ts
│   ā”œā”€ā”€ types/            # TypeScript type definitions
│   ā”œā”€ā”€ utils/            # Helper functions
│   └── index.ts          # Main server entry point
ā”œā”€ā”€ dist/                 # Built output
└── __tests__/            # Test files
```

### Running Tests

```bash
# Run all tests
pnpm test:run

# Run with coverage
pnpm test:coverage

# Watch mode for development
pnpm test
```

## Security

### Credential Management

**Best Practices:**
- āœ… Use environment variables for credentials
- āœ… Use `.env` files (ensure `.env` is in `.gitignore`)
- āœ… Use MCP configuration `env` or `envFile` options
- āŒ Never hardcode credentials in configuration files
- āŒ Never commit credentials to version control

### Environment Variables

Create a `.env` file in the project root:
```bash
GARMIN_USERNAME=your_username
GARMIN_PASSWORD=your_password
```

### Testing Locally

For local development, use `.mcp.json` (gitignored):
```json
{
  "mcpServers": {
    "garmin-connect": {
      "command": "node",
      "args": ["./dist/index.js"],
      "envFile": ".env"
    }
  }
}
```

### API Rate Limits

The server includes automatic rate limiting and error handling for Garmin Connect API:
- Small delays between batch requests (100ms)
- Graceful error handling for failed requests
- Maximum activity limits to prevent overwhelming the API

## Troubleshooting

### Common Issues

**Authentication Failed**
- Verify credentials in `.env` file
- Check that MCP configuration points to correct `.env` or has correct `env` values
- Ensure Garmin account is active and accessible

**No Data Returned**
- Verify your Garmin device has synced recently
- Check that you're querying dates with actual data
- Ensure your Garmin account has the requested data types

**Response Too Large**
- Use `summary: true` for condensed results
- Reduce date ranges for volume queries
- Filter by specific activity types
- Disable detailed breakdowns (`includeActivityBreakdown: false`)

**Server Not Starting**
- Ensure Node.js version is 20 or higher
- Run `pnpm build` to rebuild after changes
- Check server logs for authentication errors

## Contributing

Contributions are welcome! Please ensure:
- All tests pass (`pnpm test:run`)
- Type checking passes (`pnpm typecheck`)
- Code follows existing style guidelines
- New features include tests

## License

MIT

## Version

Current version: 0.1.0

For updates and changelog, see the [releases page](https://github.com/your-repo/releases).

TDQS

A3.5/5.0

Scored across 16 tools

Disambiguation4/5

Tools are mostly distinct, but get_daily_overview overlaps with multiple individual metric tools (e.g., get_sleep_data, get_health_metrics), potentially causing confusion about which to use for a specific metric.

Naming Consistency5/5

All tools use a consistent snake_case verb_noun pattern (e.g., get_activities, create_running_workout, unschedule_workout), making the naming predictable and easy to navigate.

Tool Count4/5

16 tools is slightly above the ideal range but still reasonable given the domain covers activities, workouts, health metrics, and scheduling; no tool feels superfluous.

Completeness3/5

The set lacks update functionality for any resource and omits some common Garmin metrics like steps or floors, though the core read/create/delete/schedule workflow for workouts is covered.

Maintenance

ActivityInactive
ResponsivenessNo issues