MCP connector · self-hosted · zero third-party server

Your Garmin data,
in Claude.

One command installs a small connector on your own machine. Your Garmin email and password go from your browser to that machine to Garmin — and nowhere else. No hosting provider, and not this project, can ever see them.

$ curl -fsSL https://raw.githubusercontent.com/devfrp/mcp-garmin-for-ia/main/get.sh | sh
00

Nothing in the middle

Most connectors ask you to hand your Garmin credentials to somebody else's server. This one runs on hardware you control — a laptop, a home server, a Proxmox container, a VPS. The installer sets everything up under your own user, registers the connector as a service that starts with the machine (systemd or launchd) and prints the sign-in links. OAuth tokens live in ~/.config/garmin-mcp/; the password is never stored. It works with Claude Code, Claude Desktop, claude.ai in the browser, and any other MCP client.

01

What Claude can read

Nine tools, straight from the Garmin Connect API — read-only.

Training

Activities

The activity list, and the full detail of any single one — splits, laps, the whole record.

Day

Daily summary

Steps, calories, intensity minutes, floors — the day at a glance.

Recovery

Sleep

Stages, duration and sleep score, night by night.

Cardio

Heart rate

Resting heart rate and the intraday series.

Energy

Body Battery

The charge/drain curve across the day.

Load

Stress & HRV

Stress levels and heart-rate variability — the two that say whether to push or rest.

Account

User profile

The profile behind the numbers, so the figures get read in context.

Any client

Plain MCP

No Claude-only trick: any MCP client can point at the same endpoint.

02

Install

Linux and macOS. The script installs Tailscale when it needs it (--tailscale / --funnel) and --no-sudo forbids any privilege escalation — implicit when running as root.

Personal machine

curl -fsSL https://raw.githubusercontent.com/devfrp/mcp-garmin-for-ia/main/get.sh | sh

Home server / LXC / VPS

# LAN + Tailscale (home server)
… | sh -s -- --server

# bind to the Tailscale IP only (VPS with a public IP)
… | sh -s -- --server --tailscale

# + a permanent public HTTPS URL for claude.ai
… | sh -s -- --funnel

Sign in to Garmin

# open the page printed by the installer
http://127.0.0.1:8765/setup        # local
http://<server-ip>:8765/setup      # LAN / tailnet

MFA is supported. Sign-in endpoints only ever answer on private addresses — never on the public HTTPS entry points.

CLI

garmin-mcp               # start the connector
garmin-mcp login         # sign in from the terminal
garmin-mcp url           # print your MCP URL
garmin-mcp tunnel        # Cloudflare quick tunnel
garmin-mcp logout        # disconnect Garmin
garmin-mcp rotate-token  # new token, old URLs die
03

Connect a client

Local clients use the token URL. claude.ai needs HTTPS and OAuth — the connector implements both.

ClientWhat to useTransport
Claude Codeclaude mcp add -s user --transport http garmin "<MCP URL>"TOKEN
Claude Desktop
and other local MCP clients
http://…:8765/garmin/?token=…TOKEN
claude.ai (browser)
Settings → Connectors → Add custom connector
https://<machine>.<tailnet>.ts.net/garmin/OAUTH
  • 1 · HTTPS
    Get a public address · --funnel at install time gives a permanent https://<machine>.<tailnet>.ts.net that survives reboots — or use the Create HTTPS link button on the setup page for a Cloudflare quick tunnel, whose URL changes at every restart.
  • 2 · PASTE
    Add the connector · paste the HTTPS base URL followed by /garmin/, with no token.
  • 3 · APPROVE
    Authorize · claude.ai opens the connector's authorization page: paste the access token from garmin-mcp url or the setup page, and approve. The authorization persists.
  • IF IT FAILS
    DNS still propagating · if claude.ai cannot reach the server right after enabling Funnel, wait a few minutes. If it persists, rename the machine in the Tailscale admin console — a fresh DNS name resolves immediately — and re-run the installer.
04

How it works

One process on your machine, two ways in — and only one of them is reachable from the internet.

browserSigns in on the setup page — the password goes straight to Garmin SSO and is never stored
garmin-mcpThe connector, on your machine · OAuth tokens in ~/.config/garmin-mcp/ · talks to Garmin SSO + the Connect API
/garmin/MCP endpoint — the per-install token as ?token=, as a path prefix /t/<token>/garmin/, or as a Bearer header ← Claude Code / Desktop
public HTTPSFunnel or quick tunnel — only the MCP endpoint and the OAuth surface answer; sign-in, health and disconnect stay private, everything else returns 404 ← claude.ai (OAuth 2.1 + PKCE)

Internet scanners probing a public address are normal — everything they touch returns 404.

Proxmox LXCWhat to do
Runs as root
without ever calling sudo
Installs a system-wide systemd unit that starts with the CT.
Tailscale needs /dev/net/tunIf the container lacks it, the script stops and prints the exact two lines to add to /etc/pve/lxc/<CTID>.conf on the Proxmox host.
Debian containersNeed apt install python3-venv first.