Garmin Personal MCP

io.github.Mason-Levyy由 GitHub 账号 Mason-Levyy 发布v0.3.0更新于 Nov 3, 2026

Garmin Connect on Garmin's official Personal API: sleep, HRV, body battery, activities.

已验证STDIO仅桌面位置与生活数据与分析

概览

Garmin Personal 的本地 MCP 服务;无需登录;STDIO。

暂无 AI 概览:以下信息来自注册中心条目和服务本身。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Garmin Personal MCP,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

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.

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):

    bash
    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

    bash
    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:

    json
    {  "mcpServers": {    "garmin": {      "command": "uvx",      "args": ["garmin-personal-mcp"]    }  }}
    VS Code, Codex CLI, Gemini CLI

    VS Code (or use the button above):

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

    Codex CLI:

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

    Gemini CLI:

    bash
    gemini mcp add garmin uvx garmin-personal-mcp
  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:

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:

bash
mkdir -p downloadsdocker 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:

dotenv
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:

bash
docker compose run --rm garmin auth

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

Start the server

bash
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:

yaml
    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:

bash
docker compose build

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

bash
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": [...]}.

ToolWhat it returns
garmin_get_dayOne day at a glance: summary, sleep, HRV, Body Battery, stress, and activities
garmin_get_daily_summaryEvery all-day wellness total for one date
garmin_get_daily_summariesDaily summaries across a range (trends over weeks or months)
garmin_get_stepsDaily steps, distance, and goal
garmin_get_stressDaily stress level and time in each stress band
garmin_get_hydrationDaily intake, goal, and sweat loss
garmin_get_body_batteryDaily charge/drain and the events behind it; chunks for intraday lows/highs
garmin_get_heart_rateResting/min/max HR, 7-day resting average, abnormal HR alerts; samples on request
garmin_get_spo2Pulse ox averages, hourly averages, acclimation; readings on request
garmin_get_wellness_activitiesWellness activities with summary values and time in zones
garmin_get_sleepOne night in full: score, stages, timings, overnight vitals
garmin_get_sleep_summariesNightly sleep records across a range
garmin_get_hrvOne night of HRV with every reading
garmin_get_hrv_summariesNightly HRV, weekly average, baseline, and status across a range
garmin_get_weightDaily weight summaries, range average, and adjacent weigh-ins; every weigh-in with include_all
garmin_get_weight_goalsWeight goals in effect and their target ranges
garmin_get_food_logGarmin Connect nutrition log: foods, nutrients, goals, meals
garmin_search_activitiesActivities with every filter Garmin supports (type, dates, distance, power, area, dives, ...)
garmin_get_activityOne activity in full, with splits
garmin_get_activity_workoutsThe structured workout followed during an activity
garmin_download_activitySave an activity's original file (ZIP with the .fit) on the server's machine
garmin_get_profileUnits, formats, time zone, and training-day preferences
garmin_get_heart_rate_zonesZone floors per sport and the HRs they're based on
garmin_get_fitness_ageFitness age, achievable fitness age, and its components
garmin_get_menstrual_cycleCycle phase, day, fertile window, and predictions
garmin_get_menstrual_dayOne day's logged symptoms, flow, and cycle detail

Weights are in grams, distances in meters, and durations in seconds, as Garmin returns them.

Remote / HTTP mode

The default transport is stdio. For network clients:

bash
garmin-personal-mcp --http --host 127.0.0.1 --port 8491

This serves streamable HTTP at /mcp. There is no built-in authentication. Never expose it to the internet. Bind to localhost and front it with something that authenticates for you: a VPN or tailnet (e.g. tailscale serve), an authenticating reverse proxy, or an OAuth-aware MCP gateway. Behind a proxy, pass --allowed-host <proxy hostname> (repeatable) so the DNS-rebinding check accepts its Host header.

Configuration

VariablePurposeDefault
GARMIN_PERSONAL_API_KEYPersonal API key; overrides the saved key file–
GARMIN_MCP_DOWNLOAD_DIRWhere garmin_download_activity saves files; the tool can't write outside it~/Downloads/garmin (platform downloads dir)

Troubleshooting

  • "Garmin rejected the Personal API key": the key expired or was deleted. Create a new one and run garmin-personal-mcp auth.
  • "No usable Garmin Personal API key was found": run garmin-personal-mcp auth, or set GARMIN_PERSONAL_API_KEY in the client config.
  • {"no_data": ...}: Garmin has nothing for that date yet (today's HRV before you've slept, for example), or your device doesn't record that metric.
  • HTTP 400 on a long range: an endpoint without a documented limit rejected the range. Ask for a shorter one.

FAQ

Is this the official Garmin API? Yes. It uses Garmin's Personal API, which anyone with a Garmin Connect account can enable without applying, through Garmin's Apache-licensed Python client. The project itself is independent.

Can it change my Garmin data? No. The Personal API is read-only. The one tool that writes anything, garmin_download_activity, saves a file on your own machine.

Which MCP clients does it work with? Any client that runs a stdio or streamable HTTP server, including Claude Desktop, Claude Code, Cursor, Windsurf, Cline, and VS Code. AI coding agents can follow llms-install.md.

Where does my data go? The server talks only to Garmin. Your key and bearer token stay in ~/.config/garmin/. Tool results go to whichever MCP client and model you connect it to.

Can I use it for other people's accounts? No. Garmin's Personal API is for your own data. Apps serving other users need Garmin's business developer program.

How it works

  • garmin-personal-mcp auth saves the key; each call exchanges it for a bearer token through Garmin's PersonalApiAuthenticator, which caches the token until an hour before it expires. A token rejected early gets one retry with a fresh exchange.
  • Each tool maps to one endpoint on personal.connectapi.garmin.com (garmin_get_day combines several). Ranges longer than an endpoint's documented maximum are fetched in consecutive windows and concatenated.
  • Bulky per-minute sample arrays are dropped by default to keep responses readable for a model; include_samples or chunks bring them back.

Development

bash
git clone https://github.com/Mason-Levyy/garmin-personal-mcpcd garmin-personal-mcpuv syncuv run pytest

Tests run against synthetic fixtures; no account needed. Lint and formatting are enforced with ruff (uv run ruff check ., uv run ruff format .).

Contributing

Issues and pull requests are welcome, especially when Garmin adds endpoints to the Personal API. See CONTRIBUTING.md for setup, style, and the PR checklist, and SECURITY.md for how to report vulnerabilities privately. Release history is in CHANGELOG.md.

Support the project

If this server saves you time, please star the repo. Stars are how other Garmin users find it in GitHub search and MCP directories. Bug reports and endpoint requests are just as welcome in issues.

License

MIT. Garmin and Garmin Connect are trademarks of Garmin Ltd. or its subsidiaries; this project is not affiliated with or endorsed by Garmin.

来源:README.md,提交 e2becec

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

4
  1. v0.3.0最新Nov 3, 2026
  2. v0.2.0Oct 29, 2026
  3. v0.1.1Oct 23, 2026
  4. v0.1.0Oct 22, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分