SkillAgentSearch skills...

garmin-personal-mcp

MCP server for Garmin Connect on Garmin's official Personal API: sleep, HRV, body battery, activities, and more from Claude or any MCP client

Install / Use

claude mcp add Mason-Levyy -- npx -y github:Mason-Levyy/garmin-personal-mcp

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

87/100

Supported Platforms

Claude Code
Claude Desktop

Our assessment of garmin-personal-mcp

garmin-personal-mcp scores 87/100 on our quality scale, 2087th of 4,664 Development & Engineering skills we index (top 45%).

Its MCP Server is 16 KB long, well organised into 20 sections with 10 code examples: a thorough specification that gives an agent plenty to work with.

It has 43 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
7/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated yesterday, so garmin-personal-mcp is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 97/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

garmin-personal-mcp compared with similar skills

All 4 of these similar skills score higher than garmin-personal-mcp; compare them before choosing.

SkillScoreStarsUpdatedFormat
garmin-personal-mcp (this skill)by Mason-Levyy87431d agoMCP Server
Agent-Reachby Panniantong100106.6k5d agoCLAUDE.md
taste-skillby Leonxlnx100106.0ktodayCLAUDE.md
headroomby headroomlabs-ai10078.3ktodayCLAUDE.md
ai-job-searchby ai-job-search-dev10067.6k3d agoCLAUDE.md

Frequently asked questions

How do I install garmin-personal-mcp?
Run claude mcp add Mason-Levyy -- npx -y github:Mason-Levyy/garmin-personal-mcp. The install tabs above show the steps for each supported agent.
Which AI agents does garmin-personal-mcp work with?
It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
Is garmin-personal-mcp safe to use?
It is MIT-licensed and scores 97/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is garmin-personal-mcp still maintained?
The repository was last updated yesterday, so garmin-personal-mcp is actively maintained.
<div align="center"> <img src="https://raw.githubusercontent.com/Mason-Levyy/garmin-personal-mcp/main/assets/logo.png" alt="" width="120">

Garmin Personal MCP

Ask your AI about your Garmin data, on Garmin's official API.

Mason-Levyy/garmin-personal-mcp MCP server PyPI CI Python GitHub stars License: MIT

Install in Cursor Install in VS Code Install in VS Code Insiders

Quickstart · Tools · Authentication · Changelog

</div>

Garmin Personal MCP is a free, open-source MCP server that connects your Garmin Connect account to Claude, Cursor, VS Code, or any other MCP client. Ask about last night's sleep, HRV trends, Body Battery, stress, training load, weight, or a specific run, all from your real Garmin account. It runs on Garmin's official Personal API with a revocable key, so it never needs your Garmin password, and it's read-only.

Published on PyPI as garmin-personal-mcp and in the official MCP Registry as io.github.Mason-Levyy/garmin-personal-mcp.

<!-- mcp-name: io.github.Mason-Levyy/garmin-personal-mcp -->

Unofficial project, official API. This isn't made by Garmin, but it only talks to Garmin's documented Personal API through Garmin's own Python client.

How is this different from other Garmin MCP servers?

Most Garmin MCP servers sign in with your Garmin password through the unofficial garminconnect library, which breaks whenever Garmin changes its login. In October 2026 Garmin opened a Personal API for individuals. This server uses it:

  • No password, no scraping: a revocable Personal API key you create in Garmin Connect, exchanged for short-lived tokens
  • The whole Personal API: every working endpoint in Garmin's reference has a tool, with every documented filter
  • Any date range: ranges longer than an endpoint allows (28 days for steps, 31 for sleep, and so on) are split into requests for you
  • Model-sized responses: all-day sample arrays are left out unless you ask for them
  • Read-only: the Personal API can't change your account, and neither can this server

Quickstart

  1. Save your Personal API key (one-time; see Authentication):

    uvx garmin-personal-mcp auth
    
  2. Add the server to your client. The install buttons at the top do this in one click for Cursor and VS Code.

    Claude Code

    claude mcp add garmin -- uvx garmin-personal-mcp
    

    Or install it as a plugin, which asks for your key in place of step 1:

    /plugin install garmin-personal-mcp --marketplace Mason-Levyy/garmin-personal-mcp
    

    Claude Desktop (claude_desktop_config.json), Cursor (~/.cursor/mcp.json), Windsurf (~/.codeium/windsurf/mcp_config.json), and Cline (cline_mcp_settings.json) all take the same entry:

    {
      "mcpServers": {
        "garmin": {
          "command": "uvx",
          "args": ["garmin-personal-mcp"]
        }
      }
    }
    
    <details> <summary><b>VS Code, Codex CLI, Gemini CLI</b></summary>

    VS Code (or use the button above):

    code --add-mcp '{"name":"garmin","command":"uvx","args":["garmin-personal-mcp"]}'
    

    Codex CLI:

    codex mcp add garmin -- uvx garmin-personal-mcp
    

    Gemini CLI:

    gemini mcp add garmin uvx garmin-personal-mcp
    
    </details>
  3. Ask it something: "how did I sleep last night?", "is my HRV trending down this month?", "compare my last three long runs".

Requires uv. Any MCP client that speaks stdio or streamable HTTP works, not just Claude.

Finding this useful? A ⭐ on GitHub helps other Garmin users find it.

Authentication

  1. Sign in to Garmin Connect on the web and open Settings → Personal API.
  2. Create a key and choose how long it lasts (30 days to a year). Garmin shows it once.
  3. Run garmin-personal-mcp auth and paste it at the hidden prompt. The server checks it with Garmin before saving it to ~/.config/garmin/connect-personal-api-key with owner-only permissions.

Where there's no terminal to prompt in (a script, or a shell an agent runs), pipe the key in instead, e.g. pbpaste | garmin-personal-mcp auth.

garmin-personal-mcp auth --check reports whether the saved key still works, without prompting. Garmin emails you about a week before a key expires: create a new one and run auth again. No restart is needed; the server reads the key on every call.

Instead of the key file you can set GARMIN_PERSONAL_API_KEY, which takes precedence. The key file and bearer-token cache are the same ones Garmin's gc-personal CLI uses, so a key saved by either works for both.

Docker Compose

Run the server as a background HTTP service using the prebuilt image. Save this as compose.yaml:

services:
  garmin:
    image: ghcr.io/mason-levyy/garmin-personal-mcp:latest
    command: ["--http", "--host", "0.0.0.0"]
    environment:
      - GARMIN_PERSONAL_API_KEY
    ports:
      - "127.0.0.1:8491:8491"
    volumes:
      - garmin-config:/home/garmin/.config/garmin
      - ./downloads:/home/garmin/Downloads/garmin
    restart: unless-stopped

volumes:
  garmin-config:

latest is the newest release, the same version PyPI serves. To stay on one version, use a version tag such as :0.2.0 instead.

From the directory containing compose.yaml, create the downloads folder and pull the image:

mkdir -p downloads
docker compose pull

Activity files from garmin_download_activity land in ./downloads. The tool reports the path inside the container (/home/garmin/Downloads/garmin/...), which is the same file. The container runs as uid 1000, so on Linux, if your uid isn't 1000, run sudo chown 1000 downloads.

Don't mount an existing ~/.config/garmin from the host into the container. The key file there is readable only by its owner, so the container can't read it unless your uid is 1000. Use one of the options below instead.

The container paths above and uid 1000 stay the same across releases.

Authentication

Choose one of these authentication options:

1. Add your API key to a .env file

Create .env next to compose.yaml and add your Personal API key:

GARMIN_PERSONAL_API_KEY='your-personal-api-key'

Compose loads this file automatically. You do not need to run auth.

2. Use the interactive auth command

Leave GARMIN_PERSONAL_API_KEY unset in your shell and .env, then run:

docker compose run --rm garmin auth

Paste your Personal API key at the prompt. It is saved for subsequent starts.

Start the server

docker compose up -d

In your MCP client, add a Streamable HTTP server with the URL http://127.0.0.1:8491/mcp.

The server only accepts requests addressed to 127.0.0.1 or localhost, and it has no authentication. To reach it from another machine, keep the port on 127.0.0.1, put an authenticating proxy or tailnet in front (see Remote / HTTP mode), and add the hostname clients use to command:

    command: ["--http", "--host", "0.0.0.0", "--allowed-host", "garmin.example.ts.net"]

Without --allowed-host, requests to any other hostname are rejected.

Build from source

Clone the repository and use compose.yaml in its root, which builds the image from source. From the repository directory, run:

docker compose build

Then follow the authentication and startup steps above. After updating the source, rebuild and restart with:

docker compose up --build -d

Tools

All tools take dates as YYYY-MM-DD. Range tools default to the 7 days ending today. Tools that return a list wrap it as {"results": [...]}.

| Tool | What it returns | | --- | --- | | garmin_get_day | One day at a glance: summary, sleep, HRV, Body Battery, stress, and activities | | garmin_get_daily_summary | Every all-day wellness total for one date | | garmin_get_daily_summaries | Daily summaries across a range (trends over weeks or months) | | garmin_get_steps | Daily steps, distance, and goal | | garmin_get_stress | Daily stress level and time in each stress band | | garmin_get_hydration | Daily intake, goal, and sweat loss | | garmin_get_body_battery | Daily charge/drain and the events behind it; chunks for intraday lows/highs | | garmin_get_heart_rate | Resting/min/max HR, 7-day resting average, abnormal HR alerts; samples on request | | garmin_get_spo2 | Pulse ox averages, hourly averages, acclimation; readings on request | | garmin_get_wellness_activities | Wellness activities with summary values and time in zones | | garmin_get_sleep | One night in full: score, stages, timings, overnight vitals | | garmin_get_sleep_summaries | Nightly sleep records across a range | | garmin_get_hrv | One night of HRV with every reading | | garmin_get_hrv_summaries | Nightly HRV, weekly average, baseline, and status across a range | | garmin_get_weight | Daily weight summaries, range average, and adjacent weigh-ins; every weigh-in with include_all | | garmin_get_weight_goals | Weight goals in effect and their target ranges | | garmin_get_food_log | Garmin Connect nutrition log: foods, nutrients, goals, meals | | garmin_search_activities | Activities with every filter Garmin supports (type, dates, distance, power, area, dives, ...) | | garmin_get_activity | One activity in full, with splits | | garmin_get_activity_workouts | The structured workout followed during an activity | | garmin_download_activity | Save an activity's original file (ZIP with the .fit) on the server's machine | | `garmi

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars43
CategoryDevelopment
Updated1d ago
Forks7

Languages

Python

Trust signals

97/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 info