Skip to main content
Glama
alexpomsft

Garmin Read-Only MCP

by alexpomsft

Garmin Read-Only MCP

A deliberately narrow Garmin Connect integration for local use with Hermes Agent. It synchronizes selected Garmin summaries into an owner-only SQLite cache, then serves only that normalized cache through three read-only MCP tools.

This project uses the community-maintained python-garminconnect client and undocumented Garmin Connect endpoints. It is not affiliated with or supported by Garmin. Endpoints may change, and automated access may carry account or terms-of-use risk. The official Garmin Connect Developer Program remains the preferred route for approved business integrations.

Security model

The design separates network access from the MCP process:

  1. garmin-readonly-auth performs a one-time interactive login in a local terminal. Password and MFA input are hidden and never accepted as command arguments.

  2. garmin-readonly-sync loads reusable local session material, fetches a bounded date window, strips upstream fields, and writes normalized summaries to SQLite.

  3. garmin-readonly-mcp imports neither the Garmin client nor session material. It reads only the normalized SQLite cache and refuses caches that are symlinks, non-regular, not owned by the current user, or accessible by group/other users.

The default state directory is:

~/.local/share/garmin-readonly-mcp/
├── tokens/          # Garmin session material, mode 0700/0600
└── cache.sqlite3    # normalized cache, mode 0600

Set the non-secret GARMIN_READONLY_HOME environment variable to use another root. Never place the state directory inside the repository.

Related MCP server: garmin-mcp-local

Data scope

The cache and MCP expose only:

  • Daily total, active, and BMR/resting calories

  • Steps and resting heart rate when available

  • Activity type, start time, duration, distance, and calories

  • Sleep duration/score, Body Battery, nightly HRV/status, and training readiness when available

They deliberately exclude:

  • Garmin profile and social data

  • Account identifiers and activity IDs

  • Device details

  • GPS coordinates, routes, and FIT/GPX/TCX files

  • Weight and body composition

  • Raw Garmin responses

  • Upload, update, schedule, or deletion operations

  • Generic or arbitrary Garmin API access

Garmin calorie values are activity context, not a command to increase food intake.

Requirements

  • Linux or another Unix-like environment with private file permissions

  • Python 3.12+

  • uv

  • A Garmin Connect account

Install

git clone https://github.com/alexpomsft/garmin-readonly-mcp.git
cd garmin-readonly-mcp
uv sync --frozen

Authenticate locally

Run this in a private local terminal—not Telegram, chat, shell history, or a shared screen:

uv run garmin-readonly-auth

The command asks locally for email, hidden password, and hidden MFA if Garmin requires it. It stores reusable session material but not the password.

Synchronize

The default synchronizes today and yesterday:

uv run garmin-readonly-sync

A bounded historical window can be requested:

uv run garmin-readonly-sync --end-date 2026-08-18 --days 14

--days must be between 1 and 31. Provider errors are replaced with a fixed public message so raw Garmin responses and authentication details are not echoed.

Run the MCP server

After at least one successful synchronization:

uv run garmin-readonly-mcp

The stdio server exposes exactly:

  • get_daily_activity(date: YYYY-MM-DD)

  • get_recent_activities(days: 1..31 = 7)

  • get_recovery_summary(date: YYYY-MM-DD)

Tool schemas reject undeclared arguments.

Connect to Hermes Agent

Use Hermes' MCP command rather than editing config.yaml manually:

hermes mcp add garmin-readonly \
  --command /absolute/path/to/garmin-readonly-mcp/.venv/bin/garmin-readonly-mcp
hermes mcp test garmin-readonly

Restart Hermes after adding the server so its tools are discovered. No credentials or session-token paths are passed to the MCP configuration; it uses the private default state root. If GARMIN_READONLY_HOME is customized, pass only that non-secret setting with hermes mcp add ... --env GARMIN_READONLY_HOME=/private/path.

Development and verification

uv sync --frozen
uv run pytest --cov=garmin_readonly_mcp --cov-report=term-missing
uv run ruff check .
uv run mypy src tests
uv run pip-audit

The implementation was developed with failing tests first. CI runs the same test, lint, type-check, and dependency-audit gates.

Limitations

  • Garmin Connect endpoints are reverse-engineered and can break without notice.

  • Garmin may rate-limit, challenge, or lock automated clients.

  • Some recovery fields are unavailable on some devices or dates and return null.

  • The local cache is a snapshot; schedule garmin-readonly-sync separately if fresher data is needed.

  • This project does not automatically modify calorie targets or provide medical advice.

See SECURITY.md for credential handling and vulnerability reporting.

A
license - permissive license
-
quality - not tested
C
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

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.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

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/alexpomsft/garmin-readonly-mcp'

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