Skip to main content
Glama

garmin-mcp

MCP server that exposes Garmin Connect data (activities, steps, sleep, heart rate, body battery, HRV, stress, etc.) as tools, backed by the garminconnect library.

Setup

  1. Copy .env.example to .env and fill in your Garmin Connect credentials:

    cp .env.example .env
  2. Install dependencies (already done in .venv):

    .venv/bin/pip install -e .
  3. Call the login tool first, before any other tool. It reuses cached session tokens from ~/.garminconnect (override with GARMIN_TOKEN_STORE) if present, otherwise logs in with GARMIN_EMAIL/GARMIN_PASSWORD. If your account has MFA enabled, login returns status: "needs_mfa" — check your email/authenticator app for the code and call submit_mfa_code with it to finish. After a successful login, tokens are cached so future runs skip login/MFA until they expire.

Related MCP server: health-mcp

Running via Docker

A prebuilt image is published to Docker Hub as zwisler/garmin-mcp (built by the .github/workflows/docker-publish.yml GitHub Actions workflow on every push to main and on v* tags).

docker run -i --rm \
  --env-file .env \
  -v garmin-mcp-tokens:/data \
  zwisler/garmin-mcp
  • -i keeps stdin open — required, since MCP talks JSON-RPC over stdio.

  • --env-file .env supplies GARMIN_EMAIL/GARMIN_PASSWORD.

  • The named volume persists cached session tokens (GARMIN_TOKEN_STORE defaults to /data/garminconnect inside the image) across container restarts, so you don't have to log in / do MFA every run.

To register this with Claude Code instead of the local venv, point .mcp.json at:

{
  "mcpServers": {
    "garmin-connect": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "--env-file", ".env", "-v", "garmin-mcp-tokens:/data", "zwisler/garmin-mcp"]
    }
  }
}

Running via docker compose

docker-compose.yml builds from the local Dockerfile (falls back to pulling zwisler/garmin-mcp if you skip build), reads .env, and persists tokens in a named volume. Use run, not up — MCP is a one-shot stdio process per client connection, not a long-running background service:

docker compose run --rm garmin-mcp

To register this with Claude Code, point .mcp.json at:

{
  "mcpServers": {
    "garmin-connect": {
      "command": "docker",
      "args": ["compose", "run", "--rm", "garmin-mcp"]
    }
  }
}

Building and pushing manually

docker build -t zwisler/garmin-mcp:latest .
docker push zwisler/garmin-mcp:latest

CI setup

The GitHub Actions workflow needs two repo secrets to push to Docker Hub:

  • DOCKERHUB_USERNAME — your Docker Hub username

  • DOCKERHUB_TOKEN — a Docker Hub access token (Account Settings → Security → New Access Token), not your password

Registering with Claude Code

This repo includes a .mcp.json pointing at the venv's Python interpreter, so Claude Code picks it up automatically when running from this directory.

To register manually elsewhere:

claude mcp add garmin-connect /Users/zwisler/PycharmProjects/garmin-mcp/.venv/bin/python /Users/zwisler/PycharmProjects/garmin-mcp/server.py

Available tools

  • login — call this first

  • submit_mfa_code(code) — only if login returned status: "needs_mfa"

  • get_user_profile

  • get_daily_summary(day)

  • get_steps(day)

  • get_heart_rate(day)

  • get_sleep(day)

  • get_body_battery(start_day, end_day)

  • get_stress(day)

  • get_hrv(day)

  • get_body_composition(day)

  • get_activities(limit, start)

  • get_activities_by_date(start_day, end_day, activity_type)

  • get_activity_details(activity_id)

  • get_activity_splits(activity_id)

  • get_race_predictions

  • get_training_readiness(day)

  • get_respiration(day)

  • get_spo2(day)

  • get_devices

  • get_personal_records

All day parameters accept YYYY-MM-DD and default to today.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    C
    maintenance
    Connects Garmin Connect data to MCP-compatible clients, providing access to fitness activities, health metrics, and training plans. It supports advanced features like headless 2FA and automated MFA retrieval to enable seamless health data interaction through natural language.
    1
    MIT
  • A
    license
    -
    quality
    C
    maintenance
    Exposes personal Garmin wellness data through MCP tools for accessing summary, sleep, HRV, heart rate, stress, body battery, and historical data.
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    MCP server that exposes Garmin Connect health and activity data (steps, sleep, stress, activities, etc.) via tools for querying, analysis, and visualization.
    Apache 2.0
  • A
    license
    B
    quality
    C
    maintenance
    Exposes personal Garmin Connect data to MCP-capable clients like Claude and Gemini. Enables querying daily stats, heart rate, sleep, activities, and managing workouts.
    16
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP server for Withings health data — sleep, activity, heart, and body metrics.

  • Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.

  • List, fetch, create, edit (replace), delete and schedule structured workouts on Garmin Connect (runn

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zwisler-a/garmin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server