@indaco/garmin-personal-mcp 0.1.1 → 0.3.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/README.md +121 -95
- package/dist/dashboard.html +7 -7
- package/dist/index.js +3163 -546
- package/package.json +1 -1
- package/prompts/dashboard-language.md +3 -0
- package/prompts/dashboard-setup.md +21 -3
- package/prompts/dashboard-widget.md +6 -1
- package/prompts/training-dashboard-freeform.md +15 -0
- package/prompts/training-dashboard-update.md +12 -0
- package/prompts/training-dashboard.md +39 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indaco/garmin-personal-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "MCP server for the official Garmin Connect Personal API",
|
|
5
5
|
"homepage": "https://github.com/indaco/garmin-personal-mcp#readme",
|
|
6
6
|
"bugs": "https://github.com/indaco/garmin-personal-mcp/issues",
|
|
@@ -10,6 +10,9 @@ Add {{language}} to my Garmin training dashboard. Use the tools of the `garmin-p
|
|
|
10
10
|
The code is the language code, for example `de`, `fr` or `pt-BR`. Send at most 150 texts in one
|
|
11
11
|
call.
|
|
12
12
|
4. If the reply lists `missing` texts for the language, translate them and call again.
|
|
13
|
+
5. If `customWidgets` of the first reply has widgets with `texts`, translate their English texts
|
|
14
|
+
(`texts.en`) the same way, and call `editDashboard` with `widgetTexts` =
|
|
15
|
+
{ "<widget id>": { "<code>": { "<key>": "<text>", ... } } }{{pathArgument}}.
|
|
13
16
|
|
|
14
17
|
Finish with one line in chat: the language code, and that the Language menu of the page shows the
|
|
15
18
|
language after a reload.
|
|
@@ -21,9 +21,9 @@ such a tool, ask the questions in chat as numbered lists, with the default first
|
|
|
21
21
|
HR zones, activity names. For me, all are selected by default; for a shared page, ask about each
|
|
22
22
|
one. The server leaves out of the file what I do not select.
|
|
23
23
|
- **Coach notes**: include (default) or leave out.
|
|
24
|
-
- **Languages**: options "
|
|
25
|
-
only" and "Italian only". Say that I can
|
|
26
|
-
opens in Italian".
|
|
24
|
+
- **Languages**: options "English and the language of my Garmin profile, opens in the profile
|
|
25
|
+
language" (default), "All: {{languageNames}}", "English only" and "Italian only". Say that I can
|
|
26
|
+
type another choice, for example "English and Italian, opens in Italian".
|
|
27
27
|
- **Themes**: options "All 11 themes, opens in midnight" (default), "Midnight only" and "Paper
|
|
28
28
|
only". Say that I can type other themes and the one it opens in: {{themes}}.
|
|
29
29
|
3. Call `writeDashboard` with `preview` = true, `weeks` = {{weeks}} and the `path`. It writes nothing.
|
|
@@ -40,12 +40,30 @@ such a tool, ask the questions in chat as numbered lists, with the default first
|
|
|
40
40
|
language. Then call `writeDashboard` again with the same `weeks`, `path` and the `notes`, without
|
|
41
41
|
`settings`: the page keeps them.
|
|
42
42
|
|
|
43
|
+
If a `writeDashboard` result has `missingWidgetTexts`, call `editDashboard` with the same `path` without
|
|
44
|
+
changes, translate the English texts of those widgets (`customWidgets[].texts.en`) into the listed
|
|
45
|
+
languages, keeping each `{placeholder}`, and call `editDashboard` with `widgetTexts` =
|
|
46
|
+
{ "<widget id>": { "<code>": { "<key>": "<text>", ... } } }.
|
|
47
|
+
|
|
43
48
|
Use only numbers of the digest. **Never invent, interpolate or estimate missing values.** If a value
|
|
44
49
|
is missing, write "n/a". If a call fails, say which one and why in one line.
|
|
45
50
|
|
|
46
51
|
Do not write or change the page yourself. Settings need a page from the template: a page designed with
|
|
47
52
|
layout freeform cannot keep them.
|
|
48
53
|
|
|
54
|
+
Automatic refresh: call `scheduleDashboardRefresh` without arguments. If its `pages` do not have
|
|
55
|
+
the `path` of the page, ask me once whether to update the page automatically. If your client has a
|
|
56
|
+
tool for questions with choices, use it: "No" (the default), every day at 07:00, weekdays at 07:00,
|
|
57
|
+
every Monday at 07:00. Say that I can also tell you when in my own words, in any language, for
|
|
58
|
+
example "Monday and Thursday at 18" or "the first day of each month at 8". If `scheduled` is true,
|
|
59
|
+
the schedule is for all the pages: offer `cron`, in words, as the first choice after "No". Say that
|
|
60
|
+
each automatic refresh replaces the data and removes the coach notes, and that the computer must be
|
|
61
|
+
on. On a yes, turn the answer into a cron expression and call `scheduleDashboardRefresh` with `cron`
|
|
62
|
+
and the `path` of the page. Tell me the schedule and the `next` runs of the reply in my language, in
|
|
63
|
+
one line.
|
|
64
|
+
|
|
49
65
|
Finish with two lines in chat: the path of the page with the command to open it (`open` on macOS,
|
|
50
66
|
`xdg-open` on Linux, `start` on Windows), and the settings that the page keeps. Later updates keep
|
|
51
67
|
the settings: for a page with another file name, ask your assistant to update that file.
|
|
68
|
+
If the last reply has `missingProfileLanguage`, add one line: my Garmin profile uses that language,
|
|
69
|
+
the page has no texts in it and shows English, and the `dashboard-language` prompt adds the language.
|
|
@@ -4,13 +4,18 @@ MCP server. Answer in my language.
|
|
|
4
4
|
1. Call `editDashboard` with no other arguments{{pathArgument}}. Read `widgetApi` (how a widget works), `catalogue` (the
|
|
5
5
|
built-in widgets) and `customWidgets`. If there is no dashboard, call `writeDashboard`{{pathWith}} first.
|
|
6
6
|
2. If a built-in widget already shows this, name it, add it with `place`, and stop.
|
|
7
|
-
3. Write the widget as `widgetApi` says: the body of a function (el, ctx), a short id
|
|
7
|
+
3. Write the widget as `widgetApi` says: the body of a function (el, ctx), a short id, a title, and
|
|
8
|
+
`texts` with every text it shows, in English and in each language of `pageLanguages`.
|
|
8
9
|
Use only values from `ctx.data`. Show `ctx.fmt.na` for a missing value. Label an estimate as one.
|
|
9
10
|
**Never invent, interpolate or estimate missing values.**
|
|
10
11
|
4. Call `editDashboard` with `widgets` = [the widget] and `place` = [{ board, widget, span }] for the
|
|
11
12
|
board that fits the idea (`all` if no board fits){{pathArgument}}.
|
|
12
13
|
5. If the reply has an error, fix the widget and call `editDashboard` again{{pathWith}}, at most 2 times.
|
|
13
14
|
|
|
15
|
+
The server also saves the widget in my widget library, so each new page gets it. To remove a
|
|
16
|
+
widget from this page only, use `removeWidgets`; to remove it from the library too, use
|
|
17
|
+
`forgetWidgets`.
|
|
18
|
+
|
|
14
19
|
You cannot open the page, so the widget is not tested. A widget that fails shows its error in its own
|
|
15
20
|
tile, and the rest of the page works.
|
|
16
21
|
|
|
@@ -27,6 +27,10 @@ of `getDashboardData` with `weeks` = {{weeks}}, which has:
|
|
|
27
27
|
`failedSections` is not empty, name those sections in chat: `zones` and `fitnessAge` are then null
|
|
28
28
|
and `hrv` can have no rows. Their widgets show "n/a".
|
|
29
29
|
- `notes`: the coach notes, a list of strings. The server escapes them as HTML.
|
|
30
|
+
- `units`: the measurement system of my Garmin profile. The data is always metric (km, m, kg,
|
|
31
|
+
pace per km). Show every distance, pace, speed, elevation and weight in my units: `metric` km,
|
|
32
|
+
/km, km/h, m, kg; `statute_us` mi, /mi, mph, ft, lb; `statute_uk` mi, /mi, mph, m, lb. Without
|
|
33
|
+
`units`, use metric. Race names (5 km, 10 km, half marathon) stay as they are.
|
|
30
34
|
|
|
31
35
|
You do not need to call `getDashboardData`: the field names above are all the page needs.
|
|
32
36
|
|
|
@@ -305,5 +309,16 @@ to phone width (the tab bar scrolls horizontally, the page does not). Make the t
|
|
|
305
309
|
keyboard. Put tooltips on every chart and units on every axis. Use your own visual identity: no
|
|
306
310
|
third-party app names, logos or brand colours.
|
|
307
311
|
|
|
312
|
+
Automatic refresh: call `scheduleDashboardRefresh` without arguments. If its `pages` do not have
|
|
313
|
+
the `path` of the page, ask me once whether to update the page automatically. If your client has a
|
|
314
|
+
tool for questions with choices, use it: "No" (the default), every day at 07:00, weekdays at 07:00,
|
|
315
|
+
every Monday at 07:00. Say that I can also tell you when in my own words, in any language, for
|
|
316
|
+
example "Monday and Thursday at 18" or "the first day of each month at 8". If `scheduled` is true,
|
|
317
|
+
the schedule is for all the pages: offer `cron`, in words, as the first choice after "No". Say that
|
|
318
|
+
each automatic refresh replaces the data and removes the coach notes, and that the computer must be
|
|
319
|
+
on. On a yes, turn the answer into a cron expression and call `scheduleDashboardRefresh` with `cron`
|
|
320
|
+
and the `path` of the page. Tell me the schedule and the `next` runs of the reply in my language, in
|
|
321
|
+
one line.
|
|
322
|
+
|
|
308
323
|
Finish with two lines in chat: what is in the dashboard with the path of the page and the command
|
|
309
324
|
to open it (`open` on macOS, `xdg-open` on Linux, `start` on Windows), and anything that was missing.
|
|
@@ -11,10 +11,22 @@ tools of the `garmin-personal` MCP server. Answer in my language.
|
|
|
11
11
|
4. If the reply lists `languages` with `missing` texts, translate them as the `dashboard-language`
|
|
12
12
|
prompt says, and call `editDashboard`{{pathWith}} to save them.
|
|
13
13
|
|
|
14
|
+
If a `writeDashboard` result has `missingWidgetTexts`, call `editDashboard`{{pathWith}} without
|
|
15
|
+
changes, translate the English texts of those widgets (`customWidgets[].texts.en`) into the listed
|
|
16
|
+
languages, keeping each `{placeholder}`, and call `editDashboard` with `widgetTexts` =
|
|
17
|
+
{ "<widget id>": { "<code>": { "<key>": "<text>", ... } } }{{pathArgument}}.
|
|
18
|
+
|
|
14
19
|
Use only numbers of the digest. **Never invent, interpolate or estimate missing values.** If a value
|
|
15
20
|
is missing, write "n/a". If a call fails, say which one and why in one line.
|
|
16
21
|
|
|
22
|
+
If the reply has `missingProfileLanguage`, add one line: my Garmin profile uses that language, the
|
|
23
|
+
page shows English, and the `dashboard-language` prompt adds the language.
|
|
24
|
+
|
|
17
25
|
Finish with two lines in chat: the period that the dashboard covers now, with the number of new
|
|
18
26
|
activities (`sync.newActivities`), and anything that was missing. If `sync.failedDays` is more than
|
|
19
27
|
0, name the dates in `sync.failedDates`. If `sync.failedSections` is not empty, name those sections
|
|
20
28
|
(HR zones, fitness age, HRV) and say that they show as "n/a".
|
|
29
|
+
|
|
30
|
+
Call `scheduleDashboardRefresh` without arguments. If its `pages` do not have this page, add one
|
|
31
|
+
line: you can update the page automatically when I ask, in my own words, for example "update it
|
|
32
|
+
every Monday at 7".
|
|
@@ -2,14 +2,38 @@ You are a data-minded endurance coach. Using the tools of the `garmin-personal`
|
|
|
2
2
|
personal **training + recovery dashboard** for the last **{{weeks}} weeks** (today is {{today}}).
|
|
3
3
|
Answer in my language.
|
|
4
4
|
|
|
5
|
-
1.
|
|
5
|
+
1. First ask two questions. If your client has a tool for questions with choices, use it; without
|
|
6
|
+
one, ask in chat as numbered lists, with the default first:
|
|
7
|
+
- **Title**: options "Keep the title" (default: the title of the page, "{{title}}" for a new
|
|
8
|
+
page) and "Type my own".
|
|
9
|
+
- **Headline** (the line under the title): options "Keep the headline" (default: the headline of
|
|
10
|
+
the page, "{{headline}}" for a new page) and "Type my own".
|
|
11
|
+
When I choose "Type my own" and give no text, ask for the text in chat.
|
|
12
|
+
2. Call `writeDashboard` with `weeks` = {{weeks}} and `layout` = "{{layout}}". The server gets the
|
|
6
13
|
data, writes the page from its template, and returns the path of the page and a digest of the
|
|
7
14
|
data. An existing page stays as a `.bak` file.
|
|
8
|
-
|
|
15
|
+
3. Write at most 5 coach notes from the digest. Each note names a specific number of the digest, for
|
|
9
16
|
example "load ratio 1.18 while HRV was under its weekly average on 3 of the last 7 nights".
|
|
10
17
|
Training suggestions only, no medical advice. Plain text, in my language.
|
|
11
|
-
|
|
12
|
-
its layout.
|
|
18
|
+
4. Call `writeDashboard` again with the same `weeks` and the `notes`, without `layout`. The page keeps
|
|
19
|
+
its layout. If I typed my own title or headline, also give `settings` = the `settings` of the
|
|
20
|
+
last result with `title` and `headline` set to my texts: the other settings of the page stay.
|
|
21
|
+
5. If the result has `missingProfileLanguage`, say first that my Garmin profile uses that language,
|
|
22
|
+
that the page has no texts in it yet, so the page shows English, and that you can add it.
|
|
23
|
+
Make that language the default of the question below instead of "No".
|
|
24
|
+
Tell me the languages of the page (`pageLanguages` of the result) and ask whether to add one.
|
|
25
|
+
If your client has a tool for questions with choices, use it, with "No" as the default and the
|
|
26
|
+
built-in languages that the page does not have: {{builtIn}}. Say that I can type any other
|
|
27
|
+
language.
|
|
28
|
+
- A built-in language: call `writeDashboard` with the same `weeks` and `notes`, and `settings` =
|
|
29
|
+
the `settings` of the last result, with `languages` = the codes of `pageLanguages` that are `en`
|
|
30
|
+
or built in, and the new code.
|
|
31
|
+
- Any other language: tell me to run the `dashboard-language` prompt with it.
|
|
32
|
+
|
|
33
|
+
If a `writeDashboard` result has `missingWidgetTexts`, call `editDashboard` without
|
|
34
|
+
changes, translate the English texts of those widgets (`customWidgets[].texts.en`) into the listed
|
|
35
|
+
languages, keeping each `{placeholder}`, and call `editDashboard` with `widgetTexts` =
|
|
36
|
+
{ "<widget id>": { "<code>": { "<key>": "<text>", ... } } }.
|
|
13
37
|
|
|
14
38
|
Use only numbers of the digest. **Never invent, interpolate or estimate missing values.** If a value
|
|
15
39
|
is missing, write "n/a". If `sync.failedDays` is more than 0, name the dates in `sync.failedDates`.
|
|
@@ -19,5 +43,16 @@ they show as "n/a". If a call fails, say which one and why in one line.
|
|
|
19
43
|
Do not write or change the page yourself, and do not call `getDashboardData`: the digest has what the
|
|
20
44
|
notes need.
|
|
21
45
|
|
|
46
|
+
Automatic refresh: call `scheduleDashboardRefresh` without arguments. If its `pages` do not have
|
|
47
|
+
the `path` of the page, ask me once whether to update the page automatically. If your client has a
|
|
48
|
+
tool for questions with choices, use it: "No" (the default), every day at 07:00, weekdays at 07:00,
|
|
49
|
+
every Monday at 07:00. Say that I can also tell you when in my own words, in any language, for
|
|
50
|
+
example "Monday and Thursday at 18" or "the first day of each month at 8". If `scheduled` is true,
|
|
51
|
+
the schedule is for all the pages: offer `cron`, in words, as the first choice after "No". Say that
|
|
52
|
+
each automatic refresh replaces the data and removes the coach notes, and that the computer must be
|
|
53
|
+
on. On a yes, turn the answer into a cron expression and call `scheduleDashboardRefresh` with `cron`
|
|
54
|
+
and the `path` of the page. Tell me the schedule and the `next` runs of the reply in my language, in
|
|
55
|
+
one line.
|
|
56
|
+
|
|
22
57
|
Finish with two lines in chat: the path of the page with the command to open it (`open` on macOS,
|
|
23
58
|
`xdg-open` on Linux, `start` on Windows), and anything that was missing.{{layoutNote}}
|