@indaco/garmin-personal-mcp 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +330 -2
- package/THIRD-PARTY-NOTICES.md +931 -0
- package/dist/dashboard.html +80 -0
- package/dist/index.js +62054 -0
- package/package.json +51 -4
- package/prompts/dashboard-language.md +15 -0
- package/prompts/dashboard-setup.md +51 -0
- package/prompts/dashboard-widget.md +18 -0
- package/prompts/training-dashboard-freeform.md +309 -0
- package/prompts/training-dashboard-update.md +20 -0
- package/prompts/training-dashboard.md +23 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alessandro Praticò
|
|
4
|
+
Copyright (c) 2026 indaco
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,331 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="assets/logo.svg" alt="" width="48" align="absmiddle" />
|
|
3
|
+
garmin-personal-mcp
|
|
4
|
+
</h1>
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
<p align="center"><b>Your Garmin training in Claude, through the official Personal API. Read-only, nothing to install.</b></p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://www.npmjs.com/package/@indaco/garmin-personal-mcp"><img src="https://img.shields.io/npm/v/@indaco/garmin-personal-mcp.svg" alt="npm version" /></a>
|
|
10
|
+
<a href="https://codecov.io/gh/indaco/garmin-personal-mcp"><img src="https://codecov.io/gh/indaco/garmin-personal-mcp/branch/main/graph/badge.svg" alt="Code coverage" /></a>
|
|
11
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg" alt="Node.js 22 or later" /></a>
|
|
12
|
+
<a href="tsconfig.json"><img src="https://img.shields.io/badge/TypeScript-strict-3178c6.svg" alt="TypeScript strict" /></a>
|
|
13
|
+
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-stdio%20server-8a2be2.svg" alt="MCP stdio server" /></a>
|
|
14
|
+
<a href="https://developer.garmin.com/gc-developer-program/personal/"><img src="https://img.shields.io/badge/Garmin-Personal%20API-007cc3.svg" alt="Garmin Connect Personal API" /></a>
|
|
15
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT" /></a>
|
|
16
|
+
<a href="https://www.jetify.com/devbox/docs/contributor-quickstart/"><img src="https://www.jetify.com/img/devbox/shield_galaxy.svg" alt="Built with Devbox" /></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<b><a href="#quick-start">Quick start</a></b> ·
|
|
21
|
+
<b><a href="#prompts">Prompts</a></b> ·
|
|
22
|
+
<b><a href="#dashboard-setup">Dashboard setup</a></b> ·
|
|
23
|
+
<b><a href="#tools">Tools</a></b> ·
|
|
24
|
+
<b><a href="#presets-or-freeform">Presets or freeform</a></b> ·
|
|
25
|
+
<b><a href="guide/dashboard.md">Dashboard guide</a></b> ·
|
|
26
|
+
<b><a href="guide/how-it-works.md">How it works</a></b> ·
|
|
27
|
+
<b><a href="guide/troubleshooting.md">Troubleshooting</a></b>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="assets/dashboard.gif" alt="The training dashboard: the All board, load against recovery, the Run board, strength trends, edit mode (drag a widget to a new place, hide a widget, add widgets from the catalogue to an empty board), and the light and high-contrast themes" width="800">
|
|
32
|
+
</p>
|
|
33
|
+
<p align="center">
|
|
34
|
+
<sub><i>The training dashboard with demo data.</i></sub>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
MCP server for the official Garmin Connect Personal API.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **Official and read-only**: uses the Garmin Connect Personal API. It writes nothing back.
|
|
42
|
+
- **Nothing to install**: runs with `npx`.
|
|
43
|
+
- **Laps and strength sets**: read from the original .FIT files.
|
|
44
|
+
- **Recovery data**: HRV, sleep and heart rate.
|
|
45
|
+
- **Dashboard in less than a minute**: [training-dashboard](#training-dashboard) shows your
|
|
46
|
+
training load next to recovery, in widgets that you can move, resize, hide and add. You can also
|
|
47
|
+
[let Claude design the whole page](#presets-or-freeform).
|
|
48
|
+
- **Your layout stays**: [training-dashboard-update](#training-dashboard-update) adds only the
|
|
49
|
+
new data.
|
|
50
|
+
- **A page for you or for your coach**: [dashboard-setup](#dashboard-setup) makes a personal page,
|
|
51
|
+
or a page to share with your coach or personal trainer. You select the sports and the data. The
|
|
52
|
+
data that you do not select is not in the file.
|
|
53
|
+
- **Extend it**: [dashboard-widget](#dashboard-widget) makes a new widget from your idea.
|
|
54
|
+
[dashboard-language](#dashboard-language) adds a language.
|
|
55
|
+
- **All stdio clients**: Claude Desktop, Claude Code and all other MCP clients that use stdio.
|
|
56
|
+
|
|
57
|
+
With this server, you can ask Claude:
|
|
58
|
+
|
|
59
|
+
- "List my last 5 activities, with pace and heart rate."
|
|
60
|
+
- "Show the laps of my last run."
|
|
61
|
+
- "Compare my sets of this week with the week before."
|
|
62
|
+
- "How did I sleep this week, and how was my HRV?"
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
You need Node.js 22 or later (`node --version` shows the version) and a Garmin Connect account
|
|
67
|
+
with access to the [Personal API](https://developer.garmin.com/gc-developer-program/personal/).
|
|
68
|
+
|
|
69
|
+
### 1. Create a personal API key
|
|
70
|
+
|
|
71
|
+
1. Open Garmin Connect web at <https://connect.garmin.com/app/settings/personalApiToken>.
|
|
72
|
+
2. Select _Create Key_, accept the terms, select the expiry (1 year at most) and select _Create_.
|
|
73
|
+
3. Garmin shows the key **only one time**. Save it in a file that only you can read:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
mkdir -p ~/.config/garmin-mcp
|
|
77
|
+
nano ~/.config/garmin-mcp/api-key # paste the key and save
|
|
78
|
+
chmod 600 ~/.config/garmin-mcp/api-key
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You can also give the key in the environment variable `GARMIN_PERSONAL_API_KEY`.
|
|
82
|
+
|
|
83
|
+
### 2. Connect your client
|
|
84
|
+
|
|
85
|
+
**Claude Desktop**: select Settings → Developer → _Edit Config_. Add a top-level `mcpServers` key
|
|
86
|
+
next to the keys that the file has, not in `preferences`:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"garmin-personal": {
|
|
92
|
+
"command": "npx",
|
|
93
|
+
"args": ["-y", "@indaco/garmin-personal-mcp"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Then quit Claude Desktop **fully**, including the tray icon, and start it again.
|
|
100
|
+
|
|
101
|
+
**Claude Code**: this command adds the server to all your projects:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
claude mcp add garmin-personal --scope user -- npx -y @indaco/garmin-personal-mcp
|
|
105
|
+
claude mcp list # garmin-personal: ... ✔ Connected
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Use `--scope project` to write a `.mcp.json` file that you can share in the current repository.
|
|
109
|
+
|
|
110
|
+
### 3. Ask Claude
|
|
111
|
+
|
|
112
|
+
Ask "list my last 5 activities". The first time that a garmin-personal tool asks for permission, answer
|
|
113
|
+
**Allow always** in Claude Desktop. In Claude Code, use `/permissions` and add `mcp__garmin-personal`.
|
|
114
|
+
|
|
115
|
+
## Prompts
|
|
116
|
+
|
|
117
|
+
In Claude Desktop, the prompts are in the **+** menu of the message box, under _garmin-personal_. In
|
|
118
|
+
Claude Code, they are slash commands such as `/garmin-personal:training-dashboard`.
|
|
119
|
+
|
|
120
|
+
The prompts remove all spaces around an argument, also the no-break space from a phone keyboard.
|
|
121
|
+
|
|
122
|
+
After an update of the server, the prompts and tools change only in a new Claude Code session. In
|
|
123
|
+
Claude Desktop, they change after a full restart.
|
|
124
|
+
|
|
125
|
+
### training-dashboard
|
|
126
|
+
|
|
127
|
+
The server writes the dashboard page from its template, and Claude writes the coach notes. The page
|
|
128
|
+
is one HTML file, `garmin-dashboard.html` in the data folder. It works offline.
|
|
129
|
+
|
|
130
|
+
| Argument | Values | Default |
|
|
131
|
+
| -------- | --------------------------------- | -------- |
|
|
132
|
+
| `weeks` | 1 to 52 (a larger value gives 52) | 12 |
|
|
133
|
+
| `layout` | `preset`, `blank` or `freeform` | `preset` |
|
|
134
|
+
|
|
135
|
+
- `preset` gives the built-in widgets on each board.
|
|
136
|
+
- `blank` gives empty boards: you add the widgets that you want.
|
|
137
|
+
- `freeform` lets Claude design the whole page. This takes much longer, and each page looks
|
|
138
|
+
different.
|
|
139
|
+
|
|
140
|
+
| Client | How to run it |
|
|
141
|
+
| -------------- | --------------------------------------------------------------------------- |
|
|
142
|
+
| Claude Desktop | **+** → _garmin-personal_ → `training-dashboard` → set the arguments → send |
|
|
143
|
+
| Claude Code | `/garmin-personal:training-dashboard 8` |
|
|
144
|
+
|
|
145
|
+
In Claude Code, the arguments are in order and separated by spaces: first `weeks`, then `layout`.
|
|
146
|
+
You can also give only the layout: `/garmin-personal:training-dashboard freeform`.
|
|
147
|
+
|
|
148
|
+
Claude gives you the path of the page and the command to open it. The page has a board for all
|
|
149
|
+
your training, a Recovery board and a board for each sport, with 11 themes and English and Italian
|
|
150
|
+
texts. It uses the training load, HR zones and training effect from Garmin. It labels each value
|
|
151
|
+
that it calculates as an estimate, and a missing value shows as "n/a".
|
|
152
|
+
|
|
153
|
+
[The dashboard guide](guide/dashboard.md) tells what each board shows and how to change the layout.
|
|
154
|
+
[The widget catalogue](guide/widgets.md) lists every widget.
|
|
155
|
+
|
|
156
|
+
### training-dashboard-update
|
|
157
|
+
|
|
158
|
+
This prompt replaces the data and the coach notes of the page. Your layout, your custom widgets and
|
|
159
|
+
your languages stay. Reload the page to see the new data.
|
|
160
|
+
|
|
161
|
+
| Argument | Values | Default |
|
|
162
|
+
| -------- | ----------------------------------------------------------------------- | ----------------------- |
|
|
163
|
+
| `weeks` | the weeks to cover | the weeks of the page |
|
|
164
|
+
| `path` | the dashboard file, for example `garmin-dashboard-coach.html` (`.html`) | `garmin-dashboard.html` |
|
|
165
|
+
|
|
166
|
+
In Claude Code: `/garmin-personal:training-dashboard-update coach.html` updates `coach.html`. A
|
|
167
|
+
value that ends in `.html` is the file, also in the first place.
|
|
168
|
+
|
|
169
|
+
| Client | How to run it |
|
|
170
|
+
| -------------- | -------------------------------------------------------------- |
|
|
171
|
+
| Claude Desktop | **+** → _garmin-personal_ → `training-dashboard-update` → send |
|
|
172
|
+
| Claude Code | `/garmin-personal:training-dashboard-update` |
|
|
173
|
+
|
|
174
|
+
The first call sends approximately 35 requests to Garmin. Later calls use the local cache and send
|
|
175
|
+
approximately 8.
|
|
176
|
+
|
|
177
|
+
### dashboard-setup
|
|
178
|
+
|
|
179
|
+
Claude asks you some questions, then writes a page with your answers. First, it asks who the page
|
|
180
|
+
is for:
|
|
181
|
+
|
|
182
|
+
- **Personal**: a page for you, with all your data.
|
|
183
|
+
- **Shared**: a page for your coach or personal trainer. You select each type of data to include,
|
|
184
|
+
for example HR zones yes, fitness age and sleep no.
|
|
185
|
+
|
|
186
|
+
Then Claude asks for the file (any name or path), the title, the headline, the sports, the
|
|
187
|
+
languages and the themes. The server writes only the data that you select into the file. Other data
|
|
188
|
+
is not in the file, so you can send the file safely. A personal page and a shared page can be two
|
|
189
|
+
files side by side. Each page keeps its settings on each update. The argument `weeks` is optional
|
|
190
|
+
(default 12).
|
|
191
|
+
|
|
192
|
+
| Client | How to run it |
|
|
193
|
+
| -------------- | ---------------------------------------------------- |
|
|
194
|
+
| Claude Desktop | **+** → _garmin-personal_ → `dashboard-setup` → send |
|
|
195
|
+
| Claude Code | `/garmin-personal:dashboard-setup` |
|
|
196
|
+
|
|
197
|
+
[Page settings](guide/dashboard.md#page-settings) tells more.
|
|
198
|
+
|
|
199
|
+
### dashboard-widget
|
|
200
|
+
|
|
201
|
+
This prompt makes a new widget from your idea, for example "my longest ride of each month". Claude
|
|
202
|
+
writes a small widget, and `editDashboard` stores it in the page. The widget stays after each
|
|
203
|
+
update. The argument `idea` is required. The argument `path` is optional: it is the file of the
|
|
204
|
+
page, for example `coach.html`. In Claude Code:
|
|
205
|
+
`/garmin-personal:dashboard-widget my longest ride each month coach.html`. Reload the page to see
|
|
206
|
+
the widget.
|
|
207
|
+
[Custom widgets](guide/custom-widgets.md) tells more.
|
|
208
|
+
|
|
209
|
+
### dashboard-language
|
|
210
|
+
|
|
211
|
+
This prompt adds a language to the dashboard. Claude translates the texts of the page, and
|
|
212
|
+
`editDashboard` stores them in the page. The argument `language` is optional: the default is the
|
|
213
|
+
language of the conversation. The argument `path` is optional: it is the file of the page, for
|
|
214
|
+
example `coach.html`. In Claude Code: `/garmin-personal:dashboard-language German coach.html`. A text
|
|
215
|
+
without a translation shows in English. To remove an added language, ask Claude to remove it:
|
|
216
|
+
`editDashboard` with `removeLanguages`.
|
|
217
|
+
[Languages](guide/languages.md) tells more.
|
|
218
|
+
|
|
219
|
+
## Tools
|
|
220
|
+
|
|
221
|
+
| Tool | What it gives |
|
|
222
|
+
| --------------------- | ---------------------------------------------------------------------- |
|
|
223
|
+
| `listActivities` | a summary of each activity, with pace, HR, training load and effect |
|
|
224
|
+
| `getActivity` | the details of one activity |
|
|
225
|
+
| `getActivityLaps` | the laps of an activity, from its .FIT file |
|
|
226
|
+
| `getActivitySets` | the strength sets of an activity, with the muscles, from its .FIT file |
|
|
227
|
+
| `downloadActivityFit` | saves the .FIT file of an activity in the data folder |
|
|
228
|
+
| `getHrvRange` | HRV during the night |
|
|
229
|
+
| `getDailyHeartRate` | the heart rate of a day, with the resting HR |
|
|
230
|
+
| `getSleep` | the sleep of a night, or of up to 14 nights |
|
|
231
|
+
| `getHeartRateZones` | your HR zones |
|
|
232
|
+
| `getFitnessAge` | fitness age against actual age |
|
|
233
|
+
| `getDailySummary` | steps, stress and Body Battery, for a day or a range |
|
|
234
|
+
| `getDashboardData` | all the data of the dashboard in one call, with a local cache |
|
|
235
|
+
| `writeDashboard` | writes the dashboard page |
|
|
236
|
+
| `editDashboard` | changes the layout, the custom widgets and the languages of the page |
|
|
237
|
+
| `garminGet` | all other GET endpoints of the Personal API |
|
|
238
|
+
|
|
239
|
+
[Tools](guide/tools.md) gives the endpoints, the details of each tool and the data that the
|
|
240
|
+
Personal API does not have.
|
|
241
|
+
|
|
242
|
+
## Configuration
|
|
243
|
+
|
|
244
|
+
All the settings are environment variables, and all of them are optional.
|
|
245
|
+
|
|
246
|
+
| Variable | Default | Meaning |
|
|
247
|
+
| ------------------------- | ---------------------------------------- | -------------------------------------------------------- |
|
|
248
|
+
| `GARMIN_PERSONAL_API_KEY` | not set | the personal API key. It has priority over the key file. |
|
|
249
|
+
| `GARMIN_API_KEY_FILE` | `~/.config/garmin-mcp/api-key` | the file with the API key |
|
|
250
|
+
| `GARMIN_DATA_DIR` | `~/workspace/garmin-data` | the data folder |
|
|
251
|
+
| `GARMIN_BASE_URL` | `https://personal.connectapi.garmin.com` | the Personal API host |
|
|
252
|
+
|
|
253
|
+
To set a variable in Claude Desktop, add an `env` object next to `args`:
|
|
254
|
+
|
|
255
|
+
```json
|
|
256
|
+
"env": { "GARMIN_DATA_DIR": "/absolute/path/to/garmin-data" }
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
In Claude Code, add `--env GARMIN_DATA_DIR=/path/to/garmin-data` to `claude mcp add`.
|
|
260
|
+
|
|
261
|
+
[The data folder](guide/tools.md#the-data-folder) lists the files that the server keeps and its
|
|
262
|
+
log.
|
|
263
|
+
|
|
264
|
+
## Presets or freeform
|
|
265
|
+
|
|
266
|
+
In many setup guides for Claude and Garmin, Claude reads the data and writes the whole dashboard
|
|
267
|
+
page. With a preset, the server writes the page from a tested template, and Claude writes only the
|
|
268
|
+
coach notes. My measurements for a first build:
|
|
269
|
+
|
|
270
|
+
| First build | Time | Cost |
|
|
271
|
+
| ---------------------- | ------------ | ------------ |
|
|
272
|
+
| Preset | 34 s | $0.16 |
|
|
273
|
+
| Claude writes the page | 24 to 35 min | $6.6 to $9.2 |
|
|
274
|
+
|
|
275
|
+
For a design of your own, use `layout` = `freeform`: Claude writes the page, as in those guides.
|
|
276
|
+
|
|
277
|
+
[Presets or freeform](guide/presets.md) gives the measurements and the limits of the presets.
|
|
278
|
+
|
|
279
|
+
## Security
|
|
280
|
+
|
|
281
|
+
The server is read-only. It sends the API key only to the Garmin token endpoint, and it never logs
|
|
282
|
+
or returns the key or the access token. It refuses a key that has spaces or line breaks in it, and
|
|
283
|
+
it removes the key and the token from network error messages. If you saw your API key in a chat,
|
|
284
|
+
revoke the key on the [API key page](https://connect.garmin.com/app/settings/personalApiToken) and
|
|
285
|
+
create a new one. Your .FIT files can have your GPS track, so keep the data folder private.
|
|
286
|
+
|
|
287
|
+
[SECURITY.md](SECURITY.md) tells how the server protects your data and how to report a
|
|
288
|
+
vulnerability. Do not open a public issue for a vulnerability.
|
|
289
|
+
|
|
290
|
+
The Personal API is for personal use that is not commercial, under the terms of Garmin. Garmin
|
|
291
|
+
does not endorse this project, and the project has no affiliation with Garmin.
|
|
292
|
+
|
|
293
|
+
## Problems and solutions
|
|
294
|
+
|
|
295
|
+
| Problem | Solution |
|
|
296
|
+
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
297
|
+
| The server does not start | Make sure that Node.js is version 22 or later: `node --version`. |
|
|
298
|
+
| Claude Desktop does not find `npx` | GUI apps do not read your shell profile. Use the absolute path of `npx` (`which npx`) as the `command`. |
|
|
299
|
+
| Changes have no effect | The client keeps the old server process. Start a new Claude Code session, or quit and start Claude Desktop again. |
|
|
300
|
+
|
|
301
|
+
[Problems and solutions](guide/troubleshooting.md) has more problems, the log files, and commands
|
|
302
|
+
that test the key and the server.
|
|
303
|
+
|
|
304
|
+
## Contributing
|
|
305
|
+
|
|
306
|
+
Read [CONTRIBUTING.md](CONTRIBUTING.md). It tells how to run the server from source, and it has
|
|
307
|
+
the commands, the test rules and the code map.
|
|
308
|
+
|
|
309
|
+
To build a demo site with a year of sample data, run `pnpm build`, then
|
|
310
|
+
`node scripts/demo-data.mjs`. The script writes `demo-site/index.html` and `demo-site/demo-data.json`.
|
|
311
|
+
|
|
312
|
+
## Credits
|
|
313
|
+
|
|
314
|
+
The idea comes from [apratico/garmin-mcp](https://github.com/apratico/garmin-mcp) by Alessandro
|
|
315
|
+
Praticò: a Java MCP server for the Garmin Personal API, where Claude writes the dashboard. I
|
|
316
|
+
tested it in a fork, [indaco/garmin-mcp](https://github.com/indaco/garmin-mcp), and then made this
|
|
317
|
+
server as a different solution:
|
|
318
|
+
|
|
319
|
+
- **No Java**: the server runs with `npx`. You do not need Java 21 and a jar file.
|
|
320
|
+
- **The server writes the page**: in garmin-mcp, Claude writes all of the dashboard HTML on each run. Here the server fills a tested template, and Claude writes only the coach notes. A first build takes seconds, not minutes ([measurements](#presets-or-freeform)).
|
|
321
|
+
- **Updates keep your page**: [training-dashboard-update](#training-dashboard-update) adds only the new data, and your layout stays.
|
|
322
|
+
- **Widgets that you control**: charts for training load, recovery, running and strength. In the page, you drag, resize, hide and add widgets, and select a theme.
|
|
323
|
+
- **Setup by sport**: [dashboard-setup](#dashboard-setup) makes a page with only the sports and the data that you select, for you or for your coach.
|
|
324
|
+
- **Languages and custom widgets**: [dashboard-language](#dashboard-language) and [dashboard-widget](#dashboard-widget) extend the page.
|
|
325
|
+
|
|
326
|
+
This server uses the same key file as indaco/garmin-mcp and can share its data folder.
|
|
327
|
+
|
|
328
|
+
## License
|
|
329
|
+
|
|
330
|
+
This project uses the [MIT License](LICENSE). `dist/index.js` and the dashboard page include
|
|
331
|
+
other libraries with their own licenses: [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md) lists them.
|