Garmin Workouts MCP
# 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.
TDQS
Scored across 15 tools
Most tools target distinct actions (list, get, delete, upload, validate) but there is some overlap in workout-related operations like generate_workout_data_prompt, preview_workout_payload, and get_workout_input_schema which may confuse an agent. Also, list_workouts and list_activities are distinct but could be ambiguous without descriptions.
The majority of tools follow a consistent verb_noun pattern (list_workouts, delete_workout, validate_workout, get_activity). However, 'resolve_supported_strength_exercise' and 'generate_workout_data_prompt' deviate slightly from the simpler pattern of other tools, introducing minor inconsistency.
Fifteen tools is within a reasonable range for a workout management server, covering CRUD, validation, preview, and activity retrieval. The count feels slightly heavy but each tool seems to serve a purpose, and it is not excessive for the apparent feature set.
The server covers core workout lifecycle operations (list, get, upload, delete) plus validation, preview, and schema retrieval. Missing update functionality for workouts is a notable gap, but the domain appears covered for typical workout management workflows.