intervals-icu-mcp-server 0.2.0 → 0.2.1
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/dist/client.d.ts +159 -0
- package/dist/client.js +30 -0
- package/dist/format.js +24 -10
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -32,6 +32,59 @@ export declare const ActivitySchema: z.ZodObject<{
|
|
|
32
32
|
feel: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
33
33
|
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
34
34
|
trainer: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
35
|
+
decoupling: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
36
|
+
icu_efficiency_factor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
37
|
+
icu_power_hr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
38
|
+
icu_variability_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
39
|
+
icu_pm_cp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
40
|
+
icu_rolling_ftp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
41
|
+
polarization_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
42
|
+
icu_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
43
|
+
id: z.ZodString;
|
|
44
|
+
secs: z.ZodNumber;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
id: string;
|
|
47
|
+
secs: number;
|
|
48
|
+
}, {
|
|
49
|
+
id: string;
|
|
50
|
+
secs: number;
|
|
51
|
+
}>, "many">>>;
|
|
52
|
+
icu_hr_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber, "many">>>;
|
|
53
|
+
total_elevation_loss: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
54
|
+
max_speed: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
55
|
+
min_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
56
|
+
max_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
57
|
+
icu_joules: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
58
|
+
icu_hrr: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
59
|
+
hrr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
60
|
+
start_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
61
|
+
end_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
62
|
+
}, "strip", z.ZodTypeAny, {
|
|
63
|
+
hrr?: number | null | undefined;
|
|
64
|
+
start_bpm?: number | null | undefined;
|
|
65
|
+
end_bpm?: number | null | undefined;
|
|
66
|
+
}, {
|
|
67
|
+
hrr?: number | null | undefined;
|
|
68
|
+
start_bpm?: number | null | undefined;
|
|
69
|
+
end_bpm?: number | null | undefined;
|
|
70
|
+
}>>>;
|
|
71
|
+
strain_score: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
72
|
+
hr_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
73
|
+
power_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
74
|
+
gear: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
75
|
+
id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
76
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
77
|
+
}, "strip", z.ZodTypeAny, {
|
|
78
|
+
id?: string | null | undefined;
|
|
79
|
+
name?: string | null | undefined;
|
|
80
|
+
}, {
|
|
81
|
+
id?: string | null | undefined;
|
|
82
|
+
name?: string | null | undefined;
|
|
83
|
+
}>>>;
|
|
84
|
+
device_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
85
|
+
power_meter: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
86
|
+
source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
87
|
+
compliance: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
35
88
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
36
89
|
id: z.ZodString;
|
|
37
90
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -61,6 +114,59 @@ export declare const ActivitySchema: z.ZodObject<{
|
|
|
61
114
|
feel: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
62
115
|
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
63
116
|
trainer: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
117
|
+
decoupling: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
118
|
+
icu_efficiency_factor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
119
|
+
icu_power_hr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
120
|
+
icu_variability_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
121
|
+
icu_pm_cp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
122
|
+
icu_rolling_ftp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
123
|
+
polarization_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
124
|
+
icu_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
125
|
+
id: z.ZodString;
|
|
126
|
+
secs: z.ZodNumber;
|
|
127
|
+
}, "strip", z.ZodTypeAny, {
|
|
128
|
+
id: string;
|
|
129
|
+
secs: number;
|
|
130
|
+
}, {
|
|
131
|
+
id: string;
|
|
132
|
+
secs: number;
|
|
133
|
+
}>, "many">>>;
|
|
134
|
+
icu_hr_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber, "many">>>;
|
|
135
|
+
total_elevation_loss: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
136
|
+
max_speed: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
137
|
+
min_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
138
|
+
max_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
139
|
+
icu_joules: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
140
|
+
icu_hrr: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
141
|
+
hrr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
142
|
+
start_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
143
|
+
end_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
144
|
+
}, "strip", z.ZodTypeAny, {
|
|
145
|
+
hrr?: number | null | undefined;
|
|
146
|
+
start_bpm?: number | null | undefined;
|
|
147
|
+
end_bpm?: number | null | undefined;
|
|
148
|
+
}, {
|
|
149
|
+
hrr?: number | null | undefined;
|
|
150
|
+
start_bpm?: number | null | undefined;
|
|
151
|
+
end_bpm?: number | null | undefined;
|
|
152
|
+
}>>>;
|
|
153
|
+
strain_score: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
154
|
+
hr_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
155
|
+
power_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
156
|
+
gear: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
157
|
+
id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
158
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
159
|
+
}, "strip", z.ZodTypeAny, {
|
|
160
|
+
id?: string | null | undefined;
|
|
161
|
+
name?: string | null | undefined;
|
|
162
|
+
}, {
|
|
163
|
+
id?: string | null | undefined;
|
|
164
|
+
name?: string | null | undefined;
|
|
165
|
+
}>>>;
|
|
166
|
+
device_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
167
|
+
power_meter: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
168
|
+
source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
169
|
+
compliance: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
64
170
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
65
171
|
id: z.ZodString;
|
|
66
172
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -90,6 +196,59 @@ export declare const ActivitySchema: z.ZodObject<{
|
|
|
90
196
|
feel: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
91
197
|
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
92
198
|
trainer: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
199
|
+
decoupling: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
200
|
+
icu_efficiency_factor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
201
|
+
icu_power_hr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
202
|
+
icu_variability_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
203
|
+
icu_pm_cp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
204
|
+
icu_rolling_ftp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
205
|
+
polarization_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
206
|
+
icu_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
207
|
+
id: z.ZodString;
|
|
208
|
+
secs: z.ZodNumber;
|
|
209
|
+
}, "strip", z.ZodTypeAny, {
|
|
210
|
+
id: string;
|
|
211
|
+
secs: number;
|
|
212
|
+
}, {
|
|
213
|
+
id: string;
|
|
214
|
+
secs: number;
|
|
215
|
+
}>, "many">>>;
|
|
216
|
+
icu_hr_zone_times: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber, "many">>>;
|
|
217
|
+
total_elevation_loss: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
218
|
+
max_speed: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
219
|
+
min_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
220
|
+
max_altitude: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
221
|
+
icu_joules: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
222
|
+
icu_hrr: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
223
|
+
hrr: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
224
|
+
start_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
225
|
+
end_bpm: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
226
|
+
}, "strip", z.ZodTypeAny, {
|
|
227
|
+
hrr?: number | null | undefined;
|
|
228
|
+
start_bpm?: number | null | undefined;
|
|
229
|
+
end_bpm?: number | null | undefined;
|
|
230
|
+
}, {
|
|
231
|
+
hrr?: number | null | undefined;
|
|
232
|
+
start_bpm?: number | null | undefined;
|
|
233
|
+
end_bpm?: number | null | undefined;
|
|
234
|
+
}>>>;
|
|
235
|
+
strain_score: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
236
|
+
hr_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
237
|
+
power_load: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
238
|
+
gear: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
239
|
+
id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
240
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
241
|
+
}, "strip", z.ZodTypeAny, {
|
|
242
|
+
id?: string | null | undefined;
|
|
243
|
+
name?: string | null | undefined;
|
|
244
|
+
}, {
|
|
245
|
+
id?: string | null | undefined;
|
|
246
|
+
name?: string | null | undefined;
|
|
247
|
+
}>>>;
|
|
248
|
+
device_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
249
|
+
power_meter: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
250
|
+
source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
251
|
+
compliance: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
93
252
|
}, z.ZodTypeAny, "passthrough">>;
|
|
94
253
|
export type Activity = z.infer<typeof ActivitySchema>;
|
|
95
254
|
export declare const WellnessSchema: z.ZodObject<{
|
package/dist/client.js
CHANGED
|
@@ -53,6 +53,36 @@ export const ActivitySchema = z.object({
|
|
|
53
53
|
feel: z.number().nullable().optional(),
|
|
54
54
|
description: z.string().nullable().optional(),
|
|
55
55
|
trainer: z.boolean().nullable().optional(),
|
|
56
|
+
decoupling: z.number().nullable().optional(),
|
|
57
|
+
icu_efficiency_factor: z.number().nullable().optional(),
|
|
58
|
+
icu_power_hr: z.number().nullable().optional(),
|
|
59
|
+
icu_variability_index: z.number().nullable().optional(),
|
|
60
|
+
icu_pm_cp: z.number().nullable().optional(),
|
|
61
|
+
icu_rolling_ftp: z.number().nullable().optional(),
|
|
62
|
+
polarization_index: z.number().nullable().optional(),
|
|
63
|
+
icu_zone_times: z.array(z.object({ id: z.string(), secs: z.number() })).nullable().optional(),
|
|
64
|
+
icu_hr_zone_times: z.array(z.number()).nullable().optional(),
|
|
65
|
+
total_elevation_loss: z.number().nullable().optional(),
|
|
66
|
+
max_speed: z.number().nullable().optional(),
|
|
67
|
+
min_altitude: z.number().nullable().optional(),
|
|
68
|
+
max_altitude: z.number().nullable().optional(),
|
|
69
|
+
icu_joules: z.number().nullable().optional(),
|
|
70
|
+
icu_hrr: z.object({
|
|
71
|
+
hrr: z.number().nullable().optional(),
|
|
72
|
+
start_bpm: z.number().nullable().optional(),
|
|
73
|
+
end_bpm: z.number().nullable().optional(),
|
|
74
|
+
}).nullable().optional(),
|
|
75
|
+
strain_score: z.number().nullable().optional(),
|
|
76
|
+
hr_load: z.number().nullable().optional(),
|
|
77
|
+
power_load: z.number().nullable().optional(),
|
|
78
|
+
gear: z.object({
|
|
79
|
+
id: z.string().nullable().optional(),
|
|
80
|
+
name: z.string().nullable().optional(),
|
|
81
|
+
}).nullable().optional(),
|
|
82
|
+
device_name: z.string().nullable().optional(),
|
|
83
|
+
power_meter: z.string().nullable().optional(),
|
|
84
|
+
source: z.string().nullable().optional(),
|
|
85
|
+
compliance: z.number().nullable().optional(),
|
|
56
86
|
}).passthrough();
|
|
57
87
|
export const WellnessSchema = z.object({
|
|
58
88
|
id: z.string().optional(),
|
package/dist/format.js
CHANGED
|
@@ -3,6 +3,13 @@ function n(v, unit = "") {
|
|
|
3
3
|
return "N/A";
|
|
4
4
|
return `${v}${unit}`;
|
|
5
5
|
}
|
|
6
|
+
function fmtDuration(secs) {
|
|
7
|
+
if (secs == null)
|
|
8
|
+
return "N/A";
|
|
9
|
+
const h = Math.floor(secs / 3600);
|
|
10
|
+
const m = Math.round((secs % 3600) / 60);
|
|
11
|
+
return h > 0 ? `${h}h${m}m` : `${m}m`;
|
|
12
|
+
}
|
|
6
13
|
export function formatActivity(a) {
|
|
7
14
|
const startTime = a.start_date_local
|
|
8
15
|
? new Date(a.start_date_local).toLocaleString()
|
|
@@ -11,23 +18,30 @@ export function formatActivity(a) {
|
|
|
11
18
|
`**${a.name ?? "Unnamed"}** (${a.id})`,
|
|
12
19
|
`Type: ${n(a.type)} | Date: ${startTime}`,
|
|
13
20
|
`Distance: ${n(a.distance, " m")} | Duration: ${n(a.elapsed_time, " s")} | Moving: ${n(a.moving_time, " s")}`,
|
|
14
|
-
`Elevation:
|
|
21
|
+
`Elevation: +${n(a.total_elevation_gain, " m")} / -${n(a.total_elevation_loss, " m")} | Altitude: ${n(a.min_altitude, " m")}-${n(a.max_altitude, " m")}`,
|
|
15
22
|
"",
|
|
16
23
|
"Power:",
|
|
17
24
|
` Avg: ${n(a.icu_average_watts, " W")} | Weighted Avg: ${n(a.icu_weighted_avg_watts, " W")} | FTP: ${n(a.icu_ftp, " W")}`,
|
|
18
|
-
` Training Load: ${n(a.icu_training_load)} | Intensity: ${n(a.icu_intensity)}`,
|
|
25
|
+
` Training Load: ${n(a.icu_training_load)} | Intensity: ${n(a.icu_intensity)} | VI: ${n(a.icu_variability_index)}`,
|
|
26
|
+
` Critical Power: ${n(a.icu_pm_cp, " W")} | Rolling FTP: ${n(a.icu_rolling_ftp, " W")} | Energy: ${a.icu_joules != null ? `${Math.round(a.icu_joules / 1000)} kJ` : "N/A"}`,
|
|
19
27
|
"",
|
|
20
28
|
"Heart Rate:",
|
|
21
29
|
` Avg: ${n(a.average_heartrate, " bpm")} | Max: ${n(a.max_heartrate, " bpm")}`,
|
|
22
|
-
""
|
|
23
|
-
"Other:",
|
|
24
|
-
` Cadence: ${n(a.average_cadence, " rpm")} | Calories: ${n(a.calories)} | Speed: ${n(a.average_speed, " m/s")}`,
|
|
25
|
-
` Temp: ${n(a.average_temp, "°C")} | Trainer: ${a.trainer ? "Yes" : "No"}`,
|
|
26
|
-
` RPE: ${n(a.icu_rpe ?? a.perceived_exertion)}/10 | Feel: ${n(a.feel)}/5`,
|
|
27
|
-
"",
|
|
28
|
-
"Fitness:",
|
|
29
|
-
` CTL: ${n(a.icu_ctl)} | ATL: ${n(a.icu_atl)} | TRIMP: ${n(a.trimp)}`,
|
|
30
|
+
` Decoupling: ${n(a.decoupling, "%")} | Efficiency Factor: ${n(a.icu_efficiency_factor)} | Pw:Hr: ${n(a.icu_power_hr)}`,
|
|
30
31
|
];
|
|
32
|
+
if (a.icu_hrr?.hrr != null) {
|
|
33
|
+
lines.push(` HR Recovery: -${n(a.icu_hrr.hrr, " bpm")} (${n(a.icu_hrr.start_bpm)} → ${n(a.icu_hrr.end_bpm)} bpm)`);
|
|
34
|
+
}
|
|
35
|
+
if (a.icu_zone_times?.length || a.icu_hr_zone_times?.length) {
|
|
36
|
+
lines.push("", "Zones:");
|
|
37
|
+
if (a.icu_zone_times?.length) {
|
|
38
|
+
lines.push(` Power: ${a.icu_zone_times.map((z) => `${z.id} ${fmtDuration(z.secs)}`).join(" | ")}`);
|
|
39
|
+
}
|
|
40
|
+
if (a.icu_hr_zone_times?.length) {
|
|
41
|
+
lines.push(` HR: ${a.icu_hr_zone_times.map((secs, i) => `Z${i + 1} ${fmtDuration(secs)}`).join(" | ")}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
lines.push("", "Other:", ` Cadence: ${n(a.average_cadence, " rpm")} | Calories: ${n(a.calories)} | Speed: ${n(a.average_speed, " m/s")} (max ${n(a.max_speed, " m/s")})`, ` Temp: ${n(a.average_temp, "°C")} | Trainer: ${a.trainer ? "Yes" : "No"}`, ` RPE: ${n(a.icu_rpe ?? a.perceived_exertion)}/10 | Feel: ${n(a.feel)}/5`, "", "Fitness:", ` CTL: ${n(a.icu_ctl)} | ATL: ${n(a.icu_atl)} | TRIMP: ${n(a.trimp)} | Polarization Index: ${n(a.polarization_index)}`, ` Power Load: ${n(a.power_load)} | HR Load: ${n(a.hr_load)} | Strain: ${n(a.strain_score)}`, "", "Equipment:", ` Gear: ${n(a.gear?.name)} | Device: ${n(a.device_name)} | Power Meter: ${n(a.power_meter)}`, ` Source: ${n(a.source)} | Compliance: ${a.compliance != null ? `${a.compliance}%` : "N/A"}`);
|
|
31
45
|
if (a.description)
|
|
32
46
|
lines.push("", `Description: ${a.description}`);
|
|
33
47
|
return lines.join("\n");
|