Back to the catalog

Garmin Workouts MCP

Manage Garmin Connect workouts, including strength workouts with mapped exercises.

Open source Open in the app JSON README (API)

About

Manage Garmin Connect workouts, including strength workouts with mapped exercises.

Details

Kind
MCP servers
Topic
No topic detected
Publisher
pranciskus
Origin
official
Category
ferramentas
Transport
local
Version
0.1.2
Stars
2
Last push
2026-03-09T09:13:21Z
Repository state
ativo
Language
Python
License
MIT
Added
2026-08-29 04:01:13
Updated
2026-08-29 04:01:13
Origin id
io.github.pranciskus/garmin-workouts-mcp

README

# Garmin Workouts MCP

`garmin-workouts-mcp` is a standalone MCP server for Garmin Connect workouts.

It is intended as a focused extension for workflows that need a bit more structure around Garmin workout payloads, especially strength training.

This project is packaged as a stdio MCP server and can be published as an OCI image for MCP registries and Glama deployment. It is not a standalone public HTTP MCP endpoint.

<a href="https://glama.ai/mcp/servers/pranciskus/garmin-workouts-mcp">
  <img width="380" height="200" src="https://glama.ai/mcp/servers/pranciskus/garmin-workouts-mcp/badge" alt="Garmin Workouts MCP server" />
</a>

## Additions

- Supports Garmin strength workout steps with `reps` end conditions.
- Supports exercise metadata via explicit Garmin enums or friendly aliases.
- Adds `preview_workout_payload` so payloads can be inspected before upload.
- Adds `validate_workout` for early schema and mapping errors.
- Adds `resolve_supported_strength_exercise` for quick mapping checks.
- Adds `get_workout_input_schema` for machine-readable client integration.
- Includes `walking` as a supported sport type, which is also reflected in the prompt/schema.
- Keeps the familiar list/get/delete/schedule/calendar/activity tools.

## Environment

Garmin-backed tools authenticate lazily when they are called:

- Authentication path: `GARMIN_EMAIL` and `GARMIN_PASSWORD`

The server can start without credentials. Tools that do not talk to Garmin, such as payload preview and schema inspection, still work without secrets.

## Workout Input

The upload and preview tools accept a JSON object shaped like this:

```json
{
  "name": "Upper Day",
  "type": "strength",
  "steps": [
    {
      "stepType": "warmup",
      "endConditionType": "lap.button",
      "stepDescription": "General warm-up"
    },
    {
      "stepType": "interval",
      "exercise": "incline db press",
      "endConditionType": "reps",
      "stepReps": 8,
      "stepDescription": "8-10 reps"
    },
    {
      "stepType": "rest",
      "endConditionType": "time",
      "stepDuration": 120
    }
  ]
}
```

For strength exercises, either pass a friendly alias:

```json
{ "exercise": "t bar row" }
```

or explicit Garmin enums:

```json
{
  "exercise": {
    "category": "ROW",
    "exerciseName": "T_BAR_ROW"
  }
}
```

You can also inspect the accepted structure programmatically through `get_workout_input_schema`, or resolve likely Garmin strength mappings with `resolve_supported_strength_exercise`.

## Development

Run tests in Docker Compose:

```bash
docker compose run --rm tests
```

Build the runtime image:

```bash
docker build -t garmin-workouts-mcp:local .
```

Smoke test the stdio server startup without Garmin credentials:

```bash
python - <<'PY'
import subprocess

proc = subprocess.Popen(
    ["bash", "-lc", "tail -f /dev/null | docker run --rm -i garmin-workouts-mcp:local"]
)
try:
    proc.wait(timeout=5)
    print(f"container exited early with code {proc.returncode}")
finally:
    if proc.poll() is None:
        proc.terminate()
        proc.wait()
        print("container stayed up for 5 seconds")
PY
```

## Publishing

The intended OCI image location is:

```text
ghcr.io/pranciskus/garmin-workouts-mcp
```

Registry metadata lives in [`server.json`](./server.json). The OCI image carries the required label:

```text
io.modelcontextprotocol.server.name=io.github.pranciskus/garmin-workouts-mcp
```

Glama ownership metadata lives in [`glama.json`](./glama.json). It declares the GitHub maintainer account that can claim and manage the Glama listing.

More