hevy-mcp 1.10.16 → 1.12.3
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 +42 -142
- package/dist/index.d.ts +45 -1
- package/dist/index.js +436 -562
- package/dist/index.js.map +1 -1
- package/package.json +41 -37
package/dist/index.js
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
6
|
import "@dotenvx/dotenvx/config";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
7
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
9
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
+
import { z as z42 } from "zod";
|
|
9
11
|
|
|
10
12
|
// package.json
|
|
11
13
|
var name = "hevy-mcp";
|
|
12
|
-
var version = "1.
|
|
14
|
+
var version = "1.12.2";
|
|
13
15
|
|
|
14
16
|
// src/tools/folders.ts
|
|
15
17
|
import { z } from "zod";
|
|
@@ -53,9 +55,9 @@ function determineErrorType(error, message) {
|
|
|
53
55
|
return "UNKNOWN_ERROR" /* UNKNOWN_ERROR */;
|
|
54
56
|
}
|
|
55
57
|
function withErrorHandling(fn, context) {
|
|
56
|
-
return (async (...
|
|
58
|
+
return (async (...args) => {
|
|
57
59
|
try {
|
|
58
|
-
return await fn(...
|
|
60
|
+
return await fn(...args);
|
|
59
61
|
} catch (error) {
|
|
60
62
|
return createErrorResponse(error, context);
|
|
61
63
|
}
|
|
@@ -188,8 +190,8 @@ function createEmptyResponse(message = "No data found") {
|
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
// src/tools/folders.ts
|
|
191
|
-
function registerFolderTools(
|
|
192
|
-
|
|
193
|
+
function registerFolderTools(server, hevyClient) {
|
|
194
|
+
server.tool(
|
|
193
195
|
"get-routine-folders",
|
|
194
196
|
"Get a paginated list of your routine folders, including both default and custom folders. Useful for organizing and browsing your workout routines.",
|
|
195
197
|
{
|
|
@@ -198,7 +200,12 @@ function registerFolderTools(server2, hevyClient2) {
|
|
|
198
200
|
},
|
|
199
201
|
withErrorHandling(
|
|
200
202
|
async ({ page, pageSize }) => {
|
|
201
|
-
|
|
203
|
+
if (!hevyClient) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
const data = await hevyClient.getRoutineFolders({
|
|
202
209
|
page,
|
|
203
210
|
pageSize
|
|
204
211
|
});
|
|
@@ -215,14 +222,19 @@ function registerFolderTools(server2, hevyClient2) {
|
|
|
215
222
|
"get-routine-folders"
|
|
216
223
|
)
|
|
217
224
|
);
|
|
218
|
-
|
|
225
|
+
server.tool(
|
|
219
226
|
"get-routine-folder",
|
|
220
227
|
"Get complete details of a specific routine folder by its ID, including name, creation date, and associated routines.",
|
|
221
228
|
{
|
|
222
229
|
folderId: z.string().min(1)
|
|
223
230
|
},
|
|
224
231
|
withErrorHandling(async ({ folderId }) => {
|
|
225
|
-
|
|
232
|
+
if (!hevyClient) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
const data = await hevyClient.getRoutineFolder(folderId);
|
|
226
238
|
if (!data) {
|
|
227
239
|
return createEmptyResponse(
|
|
228
240
|
`Routine folder with ID ${folderId} not found`
|
|
@@ -232,14 +244,19 @@ function registerFolderTools(server2, hevyClient2) {
|
|
|
232
244
|
return createJsonResponse(folder);
|
|
233
245
|
}, "get-routine-folder")
|
|
234
246
|
);
|
|
235
|
-
|
|
247
|
+
server.tool(
|
|
236
248
|
"create-routine-folder",
|
|
237
249
|
"Create a new routine folder in your Hevy account. Requires a name for the folder. Returns the full folder details including the new folder ID.",
|
|
238
250
|
{
|
|
239
251
|
name: z.string().min(1)
|
|
240
252
|
},
|
|
241
253
|
withErrorHandling(async ({ name: name2 }) => {
|
|
242
|
-
|
|
254
|
+
if (!hevyClient) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
const data = await hevyClient.createRoutineFolder({
|
|
243
260
|
routine_folder: {
|
|
244
261
|
title: name2
|
|
245
262
|
}
|
|
@@ -260,17 +277,22 @@ function registerFolderTools(server2, hevyClient2) {
|
|
|
260
277
|
|
|
261
278
|
// src/tools/routines.ts
|
|
262
279
|
import { z as z2 } from "zod";
|
|
263
|
-
function registerRoutineTools(
|
|
264
|
-
|
|
280
|
+
function registerRoutineTools(server, hevyClient) {
|
|
281
|
+
server.tool(
|
|
265
282
|
"get-routines",
|
|
266
283
|
"Get a paginated list of your workout routines, including custom and default routines. Useful for browsing or searching your available routines.",
|
|
267
284
|
{
|
|
268
285
|
page: z2.coerce.number().int().gte(1).default(1),
|
|
269
286
|
pageSize: z2.coerce.number().int().gte(1).lte(10).default(5)
|
|
270
287
|
},
|
|
271
|
-
withErrorHandling(async (
|
|
272
|
-
|
|
273
|
-
|
|
288
|
+
withErrorHandling(async (args) => {
|
|
289
|
+
if (!hevyClient) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
const { page, pageSize } = args;
|
|
295
|
+
const data = await hevyClient.getRoutines({
|
|
274
296
|
page,
|
|
275
297
|
pageSize
|
|
276
298
|
});
|
|
@@ -283,14 +305,19 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
283
305
|
return createJsonResponse(routines);
|
|
284
306
|
}, "get-routines")
|
|
285
307
|
);
|
|
286
|
-
|
|
308
|
+
server.tool(
|
|
287
309
|
"get-routine",
|
|
288
310
|
"Get a routine by its ID using the direct endpoint. Returns all details for the specified routine.",
|
|
289
311
|
{
|
|
290
312
|
routineId: z2.string().min(1)
|
|
291
313
|
},
|
|
292
314
|
withErrorHandling(async ({ routineId }) => {
|
|
293
|
-
|
|
315
|
+
if (!hevyClient) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
const data = await hevyClient.getRoutineById(String(routineId));
|
|
294
321
|
if (!data || !data.routine) {
|
|
295
322
|
return createEmptyResponse(`Routine with ID ${routineId} not found`);
|
|
296
323
|
}
|
|
@@ -298,7 +325,7 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
298
325
|
return createJsonResponse(routine);
|
|
299
326
|
}, "get-routine")
|
|
300
327
|
);
|
|
301
|
-
|
|
328
|
+
server.tool(
|
|
302
329
|
"create-routine",
|
|
303
330
|
"Create a new workout routine in your Hevy account. Requires a title and at least one exercise with sets. Optionally assign to a folder. Returns the full routine details including the new routine ID.",
|
|
304
331
|
{
|
|
@@ -324,9 +351,14 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
324
351
|
})
|
|
325
352
|
)
|
|
326
353
|
},
|
|
327
|
-
withErrorHandling(async (
|
|
328
|
-
|
|
329
|
-
|
|
354
|
+
withErrorHandling(async (args) => {
|
|
355
|
+
if (!hevyClient) {
|
|
356
|
+
throw new Error(
|
|
357
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
const { title, folderId, notes, exercises } = args;
|
|
361
|
+
const data = await hevyClient.createRoutine({
|
|
330
362
|
routine: {
|
|
331
363
|
title,
|
|
332
364
|
folder_id: folderId ?? null,
|
|
@@ -363,7 +395,7 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
363
395
|
});
|
|
364
396
|
}, "create-routine")
|
|
365
397
|
);
|
|
366
|
-
|
|
398
|
+
server.tool(
|
|
367
399
|
"update-routine",
|
|
368
400
|
"Update an existing routine by ID. You can modify the title, notes, and exercise configurations. Returns the updated routine with all changes applied.",
|
|
369
401
|
{
|
|
@@ -389,9 +421,14 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
389
421
|
})
|
|
390
422
|
)
|
|
391
423
|
},
|
|
392
|
-
withErrorHandling(async (
|
|
393
|
-
|
|
394
|
-
|
|
424
|
+
withErrorHandling(async (args) => {
|
|
425
|
+
if (!hevyClient) {
|
|
426
|
+
throw new Error(
|
|
427
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
const { routineId, title, notes, exercises } = args;
|
|
431
|
+
const data = await hevyClient.updateRoutine(routineId, {
|
|
395
432
|
routine: {
|
|
396
433
|
title,
|
|
397
434
|
notes: notes ?? null,
|
|
@@ -431,8 +468,8 @@ function registerRoutineTools(server2, hevyClient2) {
|
|
|
431
468
|
|
|
432
469
|
// src/tools/templates.ts
|
|
433
470
|
import { z as z3 } from "zod";
|
|
434
|
-
function registerTemplateTools(
|
|
435
|
-
|
|
471
|
+
function registerTemplateTools(server, hevyClient) {
|
|
472
|
+
server.tool(
|
|
436
473
|
"get-exercise-templates",
|
|
437
474
|
"Get a paginated list of exercise templates (default and custom) with details like name, category, equipment, and muscle groups. Useful for browsing or searching available exercises.",
|
|
438
475
|
{
|
|
@@ -441,7 +478,12 @@ function registerTemplateTools(server2, hevyClient2) {
|
|
|
441
478
|
},
|
|
442
479
|
withErrorHandling(
|
|
443
480
|
async ({ page, pageSize }) => {
|
|
444
|
-
|
|
481
|
+
if (!hevyClient) {
|
|
482
|
+
throw new Error(
|
|
483
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
const data = await hevyClient.getExerciseTemplates({
|
|
445
487
|
page,
|
|
446
488
|
pageSize
|
|
447
489
|
});
|
|
@@ -458,7 +500,7 @@ function registerTemplateTools(server2, hevyClient2) {
|
|
|
458
500
|
"get-exercise-templates"
|
|
459
501
|
)
|
|
460
502
|
);
|
|
461
|
-
|
|
503
|
+
server.tool(
|
|
462
504
|
"get-exercise-template",
|
|
463
505
|
"Get complete details of a specific exercise template by its ID, including name, category, equipment, muscle groups, and notes.",
|
|
464
506
|
{
|
|
@@ -466,7 +508,12 @@ function registerTemplateTools(server2, hevyClient2) {
|
|
|
466
508
|
},
|
|
467
509
|
withErrorHandling(
|
|
468
510
|
async ({ exerciseTemplateId }) => {
|
|
469
|
-
|
|
511
|
+
if (!hevyClient) {
|
|
512
|
+
throw new Error(
|
|
513
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
const data = await hevyClient.getExerciseTemplate(exerciseTemplateId);
|
|
470
517
|
if (!data) {
|
|
471
518
|
return createEmptyResponse(
|
|
472
519
|
`Exercise template with ID ${exerciseTemplateId} not found`
|
|
@@ -486,9 +533,9 @@ import { z as z40 } from "zod";
|
|
|
486
533
|
// src/generated/client/schemas/deletedWorkoutSchema.ts
|
|
487
534
|
import { z as z4 } from "zod";
|
|
488
535
|
var deletedWorkoutSchema = z4.object({
|
|
489
|
-
type: z4.string().describe("Indicates the type of the event (deleted)"),
|
|
490
|
-
id: z4.string().describe("The unique identifier of the deleted workout"),
|
|
491
|
-
deleted_at: z4.string().describe("A date string indicating when the workout was deleted")
|
|
536
|
+
"type": z4.string().describe("Indicates the type of the event (deleted)"),
|
|
537
|
+
"id": z4.string().describe("The unique identifier of the deleted workout"),
|
|
538
|
+
"deleted_at": z4.optional(z4.string().describe("A date string indicating when the workout was deleted"))
|
|
492
539
|
});
|
|
493
540
|
|
|
494
541
|
// src/generated/client/schemas/deleteV1WebhookSubscriptionSchema.ts
|
|
@@ -497,155 +544,142 @@ var deleteV1WebhookSubscriptionHeaderParamsSchema = z5.object({
|
|
|
497
544
|
"api-key": z5.string().uuid().describe("Your API key")
|
|
498
545
|
});
|
|
499
546
|
var deleteV1WebhookSubscription200Schema = z5.any();
|
|
500
|
-
var deleteV1WebhookSubscriptionMutationResponseSchema = z5.lazy(() => deleteV1WebhookSubscription200Schema);
|
|
501
547
|
|
|
502
548
|
// src/generated/client/schemas/exerciseTemplateSchema.ts
|
|
503
549
|
import { z as z6 } from "zod";
|
|
504
550
|
var exerciseTemplateSchema = z6.object({
|
|
505
|
-
id: z6.string().describe("The exercise template ID.")
|
|
506
|
-
title: z6.string().describe("The exercise title.")
|
|
507
|
-
type: z6.string().describe("The exercise type.")
|
|
508
|
-
primary_muscle_group: z6.string().describe("The primary muscle group of the exercise.")
|
|
509
|
-
secondary_muscle_groups: z6.array(z6.string()).describe("The secondary muscle groups of the exercise.")
|
|
510
|
-
is_custom: z6.boolean().describe("A boolean indicating whether the exercise is a custom exercise.")
|
|
551
|
+
"id": z6.optional(z6.string().describe("The exercise template ID.")),
|
|
552
|
+
"title": z6.optional(z6.string().describe("The exercise title.")),
|
|
553
|
+
"type": z6.optional(z6.string().describe("The exercise type.")),
|
|
554
|
+
"primary_muscle_group": z6.optional(z6.string().describe("The primary muscle group of the exercise.")),
|
|
555
|
+
"secondary_muscle_groups": z6.optional(z6.array(z6.string()).describe("The secondary muscle groups of the exercise.")),
|
|
556
|
+
"is_custom": z6.optional(z6.boolean().describe("A boolean indicating whether the exercise is a custom exercise."))
|
|
511
557
|
});
|
|
512
558
|
|
|
513
559
|
// src/generated/client/schemas/getV1ExerciseTemplatesExercisetemplateidSchema.ts
|
|
514
560
|
import { z as z7 } from "zod";
|
|
515
561
|
var getV1ExerciseTemplatesExercisetemplateidPathParamsSchema = z7.object({
|
|
516
|
-
exerciseTemplateId: z7.any()
|
|
562
|
+
"exerciseTemplateId": z7.any()
|
|
517
563
|
});
|
|
518
564
|
var getV1ExerciseTemplatesExercisetemplateidHeaderParamsSchema = z7.object({
|
|
519
565
|
"api-key": z7.string().uuid()
|
|
520
566
|
});
|
|
521
|
-
var getV1ExerciseTemplatesExercisetemplateid200Schema = z7.lazy(() => exerciseTemplateSchema);
|
|
522
567
|
var getV1ExerciseTemplatesExercisetemplateid404Schema = z7.any();
|
|
523
|
-
var getV1ExerciseTemplatesExercisetemplateidQueryResponseSchema = z7.lazy(() => getV1ExerciseTemplatesExercisetemplateid200Schema);
|
|
524
568
|
|
|
525
569
|
// src/generated/client/schemas/getV1ExerciseTemplatesSchema.ts
|
|
526
570
|
import { z as z8 } from "zod";
|
|
527
571
|
var getV1ExerciseTemplatesQueryParamsSchema = z8.object({
|
|
528
|
-
page: z8.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
529
|
-
pageSize: z8.coerce.number().int().default(5).describe("Number of items on the requested page (Max 100)")
|
|
572
|
+
"page": z8.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
573
|
+
"pageSize": z8.coerce.number().int().default(5).describe("Number of items on the requested page (Max 100)")
|
|
530
574
|
});
|
|
531
575
|
var getV1ExerciseTemplatesHeaderParamsSchema = z8.object({
|
|
532
576
|
"api-key": z8.string().uuid()
|
|
533
577
|
});
|
|
534
578
|
var getV1ExerciseTemplates200Schema = z8.object({
|
|
535
|
-
page: z8.number().int().default(1).describe("Current page number"),
|
|
536
|
-
page_count: z8.number().int().default(5).describe("Total number of pages"),
|
|
537
|
-
exercise_templates: z8.array(z8.lazy(() => exerciseTemplateSchema))
|
|
579
|
+
"page": z8.optional(z8.number().int().default(1).describe("Current page number")),
|
|
580
|
+
"page_count": z8.optional(z8.number().int().default(5).describe("Total number of pages")),
|
|
581
|
+
"exercise_templates": z8.optional(z8.array(z8.lazy(() => exerciseTemplateSchema)))
|
|
538
582
|
});
|
|
539
583
|
var getV1ExerciseTemplates400Schema = z8.any();
|
|
540
|
-
var getV1ExerciseTemplatesQueryResponseSchema = z8.lazy(() => getV1ExerciseTemplates200Schema);
|
|
541
584
|
|
|
542
585
|
// src/generated/client/schemas/routineFolderSchema.ts
|
|
543
586
|
import { z as z9 } from "zod";
|
|
544
587
|
var routineFolderSchema = z9.object({
|
|
545
|
-
id: z9.number().describe("The routine folder ID.")
|
|
546
|
-
index: z9.number().describe("The routine folder index. Describes the order of the folder in the list.")
|
|
547
|
-
title: z9.string().describe("The routine folder title.")
|
|
548
|
-
updated_at: z9.string().describe("ISO 8601 timestamp of when the folder was last updated.")
|
|
549
|
-
created_at: z9.string().describe("ISO 8601 timestamp of when the folder was created.")
|
|
588
|
+
"id": z9.optional(z9.number().describe("The routine folder ID.")),
|
|
589
|
+
"index": z9.optional(z9.number().describe("The routine folder index. Describes the order of the folder in the list.")),
|
|
590
|
+
"title": z9.optional(z9.string().describe("The routine folder title.")),
|
|
591
|
+
"updated_at": z9.optional(z9.string().describe("ISO 8601 timestamp of when the folder was last updated.")),
|
|
592
|
+
"created_at": z9.optional(z9.string().describe("ISO 8601 timestamp of when the folder was created."))
|
|
550
593
|
});
|
|
551
594
|
|
|
552
595
|
// src/generated/client/schemas/getV1RoutineFoldersFolderidSchema.ts
|
|
553
596
|
import { z as z10 } from "zod";
|
|
554
597
|
var getV1RoutineFoldersFolderidPathParamsSchema = z10.object({
|
|
555
|
-
folderId: z10.any()
|
|
598
|
+
"folderId": z10.any()
|
|
556
599
|
});
|
|
557
600
|
var getV1RoutineFoldersFolderidHeaderParamsSchema = z10.object({
|
|
558
601
|
"api-key": z10.string().uuid()
|
|
559
602
|
});
|
|
560
|
-
var getV1RoutineFoldersFolderid200Schema = z10.lazy(() => routineFolderSchema);
|
|
561
603
|
var getV1RoutineFoldersFolderid404Schema = z10.any();
|
|
562
|
-
var getV1RoutineFoldersFolderidQueryResponseSchema = z10.lazy(() => getV1RoutineFoldersFolderid200Schema);
|
|
563
604
|
|
|
564
605
|
// src/generated/client/schemas/getV1RoutineFoldersSchema.ts
|
|
565
606
|
import { z as z11 } from "zod";
|
|
566
607
|
var getV1RoutineFoldersQueryParamsSchema = z11.object({
|
|
567
|
-
page: z11.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
568
|
-
pageSize: z11.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
608
|
+
"page": z11.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
609
|
+
"pageSize": z11.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
569
610
|
});
|
|
570
611
|
var getV1RoutineFoldersHeaderParamsSchema = z11.object({
|
|
571
612
|
"api-key": z11.string().uuid()
|
|
572
613
|
});
|
|
573
614
|
var getV1RoutineFolders200Schema = z11.object({
|
|
574
|
-
page: z11.number().int().default(1).describe("Current page number"),
|
|
575
|
-
page_count: z11.number().int().default(5).describe("Total number of pages"),
|
|
576
|
-
routine_folders: z11.array(z11.lazy(() => routineFolderSchema))
|
|
615
|
+
"page": z11.optional(z11.number().int().default(1).describe("Current page number")),
|
|
616
|
+
"page_count": z11.optional(z11.number().int().default(5).describe("Total number of pages")),
|
|
617
|
+
"routine_folders": z11.optional(z11.array(z11.lazy(() => routineFolderSchema)))
|
|
577
618
|
});
|
|
578
619
|
var getV1RoutineFolders400Schema = z11.any();
|
|
579
|
-
var getV1RoutineFoldersQueryResponseSchema = z11.lazy(() => getV1RoutineFolders200Schema);
|
|
580
620
|
|
|
581
621
|
// src/generated/client/schemas/routineSchema.ts
|
|
582
622
|
import { z as z12 } from "zod";
|
|
583
623
|
var routineSchema = z12.object({
|
|
584
|
-
id: z12.string().describe("The routine ID.")
|
|
585
|
-
title: z12.string().describe("The routine title.")
|
|
586
|
-
folder_id: z12.number().describe("The routine folder ID.").
|
|
587
|
-
updated_at: z12.string().describe("ISO 8601 timestamp of when the routine was last updated.")
|
|
588
|
-
created_at: z12.string().describe("ISO 8601 timestamp of when the routine was created.")
|
|
589
|
-
exercises: z12.array(
|
|
590
|
-
z12.
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
})
|
|
612
|
-
).optional()
|
|
613
|
-
})
|
|
614
|
-
).optional()
|
|
624
|
+
"id": z12.optional(z12.string().describe("The routine ID.")),
|
|
625
|
+
"title": z12.optional(z12.string().describe("The routine title.")),
|
|
626
|
+
"folder_id": z12.number().describe("The routine folder ID.").nullish(),
|
|
627
|
+
"updated_at": z12.optional(z12.string().describe("ISO 8601 timestamp of when the routine was last updated.")),
|
|
628
|
+
"created_at": z12.optional(z12.string().describe("ISO 8601 timestamp of when the routine was created.")),
|
|
629
|
+
"exercises": z12.optional(z12.array(z12.object({
|
|
630
|
+
"index": z12.optional(z12.number().describe("Index indicating the order of the exercise in the routine.")),
|
|
631
|
+
"title": z12.optional(z12.string().describe("Title of the exercise")),
|
|
632
|
+
"rest_seconds": z12.optional(z12.string().describe("The rest time in seconds between sets of the exercise")),
|
|
633
|
+
"notes": z12.optional(z12.string().describe("Routine notes on the exercise")),
|
|
634
|
+
"exercise_template_id": z12.optional(z12.string().describe("The id of the exercise template. This can be used to fetch the exercise template.")),
|
|
635
|
+
"supersets_id": z12.number().describe("The id of the superset that the exercise belongs to. A value of null indicates the exercise is not part of a superset.").nullish(),
|
|
636
|
+
"sets": z12.optional(z12.array(z12.object({
|
|
637
|
+
"index": z12.optional(z12.number().describe("Index indicating the order of the set in the routine.")),
|
|
638
|
+
"type": z12.optional(z12.string().describe("The type of set. This can be one of 'normal', 'warmup', 'dropset', 'failure'")),
|
|
639
|
+
"weight_kg": z12.number().describe("Weight lifted in kilograms.").nullish(),
|
|
640
|
+
"reps": z12.number().describe("Number of reps logged for the set").nullish(),
|
|
641
|
+
"rep_range": z12.object({
|
|
642
|
+
"start": z12.number().describe("Starting rep count for the range").nullish(),
|
|
643
|
+
"end": z12.number().describe("Ending rep count for the range").nullish()
|
|
644
|
+
}).describe("Range of reps for the set, if applicable").nullish(),
|
|
645
|
+
"distance_meters": z12.number().describe("Number of meters logged for the set").nullish(),
|
|
646
|
+
"duration_seconds": z12.number().describe("Number of seconds logged for the set").nullish(),
|
|
647
|
+
"rpe": z12.number().describe("RPE (Relative perceived exertion) value logged for the set").nullish(),
|
|
648
|
+
"custom_metric": z12.number().describe("Custom metric logged for the set (Currently only used to log floors or steps for stair machine exercises)").nullish()
|
|
649
|
+
})))
|
|
650
|
+
})))
|
|
615
651
|
});
|
|
616
652
|
|
|
617
653
|
// src/generated/client/schemas/getV1RoutinesRoutineidSchema.ts
|
|
618
654
|
import { z as z13 } from "zod";
|
|
619
655
|
var getV1RoutinesRoutineidPathParamsSchema = z13.object({
|
|
620
|
-
routineId: z13.any()
|
|
656
|
+
"routineId": z13.any()
|
|
621
657
|
});
|
|
622
658
|
var getV1RoutinesRoutineidHeaderParamsSchema = z13.object({
|
|
623
659
|
"api-key": z13.string().uuid()
|
|
624
660
|
});
|
|
625
661
|
var getV1RoutinesRoutineid200Schema = z13.object({
|
|
626
|
-
routine: z13.lazy(() => routineSchema)
|
|
662
|
+
"routine": z13.optional(z13.lazy(() => routineSchema))
|
|
627
663
|
});
|
|
628
664
|
var getV1RoutinesRoutineid400Schema = z13.object({
|
|
629
|
-
error: z13.string().describe("Error message")
|
|
665
|
+
"error": z13.optional(z13.string().describe("Error message"))
|
|
630
666
|
});
|
|
631
|
-
var getV1RoutinesRoutineidQueryResponseSchema = z13.lazy(() => getV1RoutinesRoutineid200Schema);
|
|
632
667
|
|
|
633
668
|
// src/generated/client/schemas/getV1RoutinesSchema.ts
|
|
634
669
|
import { z as z14 } from "zod";
|
|
635
670
|
var getV1RoutinesQueryParamsSchema = z14.object({
|
|
636
|
-
page: z14.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
637
|
-
pageSize: z14.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
671
|
+
"page": z14.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
672
|
+
"pageSize": z14.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
638
673
|
});
|
|
639
674
|
var getV1RoutinesHeaderParamsSchema = z14.object({
|
|
640
675
|
"api-key": z14.string().uuid()
|
|
641
676
|
});
|
|
642
677
|
var getV1Routines200Schema = z14.object({
|
|
643
|
-
page: z14.number().int().describe("Current page number")
|
|
644
|
-
page_count: z14.number().int().describe("Total number of pages")
|
|
645
|
-
routines: z14.array(z14.lazy(() => routineSchema))
|
|
678
|
+
"page": z14.optional(z14.number().int().describe("Current page number")),
|
|
679
|
+
"page_count": z14.optional(z14.number().int().describe("Total number of pages")),
|
|
680
|
+
"routines": z14.optional(z14.array(z14.lazy(() => routineSchema)))
|
|
646
681
|
});
|
|
647
682
|
var getV1Routines400Schema = z14.any();
|
|
648
|
-
var getV1RoutinesQueryResponseSchema = z14.lazy(() => getV1Routines200Schema);
|
|
649
683
|
|
|
650
684
|
// src/generated/client/schemas/getV1WebhookSubscriptionSchema.ts
|
|
651
685
|
import { z as z15 } from "zod";
|
|
@@ -653,11 +687,10 @@ var getV1WebhookSubscriptionHeaderParamsSchema = z15.object({
|
|
|
653
687
|
"api-key": z15.string().uuid().describe("Your API key")
|
|
654
688
|
});
|
|
655
689
|
var getV1WebhookSubscription200Schema = z15.object({
|
|
656
|
-
url: z15.string().describe("The webhook URL")
|
|
657
|
-
auth_token: z15.string().describe("The auth token for the webhook")
|
|
690
|
+
"url": z15.optional(z15.string().describe("The webhook URL")),
|
|
691
|
+
"auth_token": z15.optional(z15.string().describe("The auth token for the webhook"))
|
|
658
692
|
});
|
|
659
693
|
var getV1WebhookSubscription404Schema = z15.any();
|
|
660
|
-
var getV1WebhookSubscriptionQueryResponseSchema = z15.lazy(() => getV1WebhookSubscription200Schema);
|
|
661
694
|
|
|
662
695
|
// src/generated/client/schemas/getV1WorkoutsCountSchema.ts
|
|
663
696
|
import { z as z16 } from "zod";
|
|
@@ -665,143 +698,133 @@ var getV1WorkoutsCountHeaderParamsSchema = z16.object({
|
|
|
665
698
|
"api-key": z16.string().uuid()
|
|
666
699
|
});
|
|
667
700
|
var getV1WorkoutsCount200Schema = z16.object({
|
|
668
|
-
workout_count: z16.number().int().default(42).describe("The total number of workouts")
|
|
701
|
+
"workout_count": z16.optional(z16.number().int().default(42).describe("The total number of workouts"))
|
|
669
702
|
});
|
|
670
|
-
var getV1WorkoutsCountQueryResponseSchema = z16.lazy(() => getV1WorkoutsCount200Schema);
|
|
671
703
|
|
|
672
704
|
// src/generated/client/schemas/workoutSchema.ts
|
|
673
705
|
import { z as z17 } from "zod";
|
|
674
706
|
var workoutSchema = z17.object({
|
|
675
|
-
id: z17.string().describe("The workout ID.")
|
|
676
|
-
title: z17.string().describe("The workout title.")
|
|
677
|
-
description: z17.string().describe("The workout description.")
|
|
678
|
-
start_time: z17.number().describe("ISO 8601 timestamp of when the workout was recorded to have started.")
|
|
679
|
-
end_time: z17.number().describe("ISO 8601 timestamp of when the workout was recorded to have ended.")
|
|
680
|
-
updated_at: z17.string().describe("ISO 8601 timestamp of when the workout was last updated.")
|
|
681
|
-
created_at: z17.string().describe("ISO 8601 timestamp of when the workout was created.")
|
|
682
|
-
exercises: z17.array(
|
|
683
|
-
z17.
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
})
|
|
700
|
-
).optional()
|
|
701
|
-
})
|
|
702
|
-
).optional()
|
|
707
|
+
"id": z17.optional(z17.string().describe("The workout ID.")),
|
|
708
|
+
"title": z17.optional(z17.string().describe("The workout title.")),
|
|
709
|
+
"description": z17.optional(z17.string().describe("The workout description.")),
|
|
710
|
+
"start_time": z17.optional(z17.number().describe("ISO 8601 timestamp of when the workout was recorded to have started.")),
|
|
711
|
+
"end_time": z17.optional(z17.number().describe("ISO 8601 timestamp of when the workout was recorded to have ended.")),
|
|
712
|
+
"updated_at": z17.optional(z17.string().describe("ISO 8601 timestamp of when the workout was last updated.")),
|
|
713
|
+
"created_at": z17.optional(z17.string().describe("ISO 8601 timestamp of when the workout was created.")),
|
|
714
|
+
"exercises": z17.optional(z17.array(z17.object({
|
|
715
|
+
"index": z17.optional(z17.number().describe("Index indicating the order of the exercise in the workout.")),
|
|
716
|
+
"title": z17.optional(z17.string().describe("Title of the exercise")),
|
|
717
|
+
"notes": z17.optional(z17.string().describe("Notes on the exercise")),
|
|
718
|
+
"exercise_template_id": z17.optional(z17.string().describe("The id of the exercise template. This can be used to fetch the exercise template.")),
|
|
719
|
+
"supersets_id": z17.number().describe("The id of the superset that the exercise belongs to. A value of null indicates the exercise is not part of a superset.").nullish(),
|
|
720
|
+
"sets": z17.optional(z17.array(z17.object({
|
|
721
|
+
"index": z17.optional(z17.number().describe("Index indicating the order of the set in the workout.")),
|
|
722
|
+
"type": z17.optional(z17.string().describe("The type of set. This can be one of 'normal', 'warmup', 'dropset', 'failure'")),
|
|
723
|
+
"weight_kg": z17.number().describe("Weight lifted in kilograms.").nullish(),
|
|
724
|
+
"reps": z17.number().describe("Number of reps logged for the set").nullish(),
|
|
725
|
+
"distance_meters": z17.number().describe("Number of meters logged for the set").nullish(),
|
|
726
|
+
"duration_seconds": z17.number().describe("Number of seconds logged for the set").nullish(),
|
|
727
|
+
"rpe": z17.number().describe("RPE (Relative perceived exertion) value logged for the set").nullish(),
|
|
728
|
+
"custom_metric": z17.number().describe("Custom metric logged for the set (Currently only used to log floors or steps for stair machine exercises)").nullish()
|
|
729
|
+
})))
|
|
730
|
+
})))
|
|
703
731
|
});
|
|
704
732
|
|
|
705
733
|
// src/generated/client/schemas/updatedWorkoutSchema.ts
|
|
706
734
|
import { z as z18 } from "zod";
|
|
707
735
|
var updatedWorkoutSchema = z18.object({
|
|
708
|
-
type: z18.string().describe("Indicates the type of the event (updated)"),
|
|
709
|
-
workout: z18.lazy(() => workoutSchema)
|
|
736
|
+
"type": z18.string().describe("Indicates the type of the event (updated)"),
|
|
737
|
+
"workout": z18.lazy(() => workoutSchema)
|
|
710
738
|
});
|
|
711
739
|
|
|
712
740
|
// src/generated/client/schemas/paginatedWorkoutEventsSchema.ts
|
|
713
741
|
import { z as z19 } from "zod";
|
|
714
742
|
var paginatedWorkoutEventsSchema = z19.object({
|
|
715
|
-
page: z19.number().int().describe("The current page number"),
|
|
716
|
-
page_count: z19.number().int().describe("The total number of pages available"),
|
|
717
|
-
events: z19.array(z19.union([z19.lazy(() => updatedWorkoutSchema), z19.lazy(() => deletedWorkoutSchema)])).describe("An array of workout events (either updated or deleted)")
|
|
743
|
+
"page": z19.number().int().describe("The current page number"),
|
|
744
|
+
"page_count": z19.number().int().describe("The total number of pages available"),
|
|
745
|
+
"events": z19.array(z19.union([z19.lazy(() => updatedWorkoutSchema), z19.lazy(() => deletedWorkoutSchema)])).describe("An array of workout events (either updated or deleted)")
|
|
718
746
|
});
|
|
719
747
|
|
|
720
748
|
// src/generated/client/schemas/getV1WorkoutsEventsSchema.ts
|
|
721
749
|
import { z as z20 } from "zod";
|
|
722
750
|
var getV1WorkoutsEventsQueryParamsSchema = z20.object({
|
|
723
|
-
page: z20.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
724
|
-
pageSize: z20.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)"),
|
|
725
|
-
since: z20.string().default("1970-01-01T00:00:00Z")
|
|
751
|
+
"page": z20.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
752
|
+
"pageSize": z20.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)"),
|
|
753
|
+
"since": z20.string().default("1970-01-01T00:00:00Z")
|
|
726
754
|
});
|
|
727
755
|
var getV1WorkoutsEventsHeaderParamsSchema = z20.object({
|
|
728
756
|
"api-key": z20.string().uuid()
|
|
729
757
|
});
|
|
730
|
-
var getV1WorkoutsEvents200Schema = z20.lazy(() => paginatedWorkoutEventsSchema);
|
|
731
758
|
var getV1WorkoutsEvents500Schema = z20.any();
|
|
732
|
-
var getV1WorkoutsEventsQueryResponseSchema = z20.lazy(() => getV1WorkoutsEvents200Schema);
|
|
733
759
|
|
|
734
760
|
// src/generated/client/schemas/getV1WorkoutsSchema.ts
|
|
735
761
|
import { z as z21 } from "zod";
|
|
736
762
|
var getV1WorkoutsQueryParamsSchema = z21.object({
|
|
737
|
-
page: z21.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
738
|
-
pageSize: z21.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
763
|
+
"page": z21.coerce.number().int().default(1).describe("Page number (Must be 1 or greater)"),
|
|
764
|
+
"pageSize": z21.coerce.number().int().default(5).describe("Number of items on the requested page (Max 10)")
|
|
739
765
|
});
|
|
740
766
|
var getV1WorkoutsHeaderParamsSchema = z21.object({
|
|
741
767
|
"api-key": z21.string().uuid()
|
|
742
768
|
});
|
|
743
769
|
var getV1Workouts200Schema = z21.object({
|
|
744
|
-
page: z21.number().int().describe("Current page number")
|
|
745
|
-
page_count: z21.number().int().describe("Total number of pages")
|
|
746
|
-
workouts: z21.array(z21.lazy(() => workoutSchema))
|
|
770
|
+
"page": z21.optional(z21.number().int().describe("Current page number")),
|
|
771
|
+
"page_count": z21.optional(z21.number().int().describe("Total number of pages")),
|
|
772
|
+
"workouts": z21.optional(z21.array(z21.lazy(() => workoutSchema)))
|
|
747
773
|
});
|
|
748
774
|
var getV1Workouts400Schema = z21.any();
|
|
749
|
-
var getV1WorkoutsQueryResponseSchema = z21.lazy(() => getV1Workouts200Schema);
|
|
750
775
|
|
|
751
776
|
// src/generated/client/schemas/getV1WorkoutsWorkoutidSchema.ts
|
|
752
777
|
import { z as z22 } from "zod";
|
|
753
778
|
var getV1WorkoutsWorkoutidPathParamsSchema = z22.object({
|
|
754
|
-
workoutId: z22.any()
|
|
779
|
+
"workoutId": z22.any()
|
|
755
780
|
});
|
|
756
781
|
var getV1WorkoutsWorkoutidHeaderParamsSchema = z22.object({
|
|
757
782
|
"api-key": z22.string().uuid()
|
|
758
783
|
});
|
|
759
|
-
var getV1WorkoutsWorkoutid200Schema = z22.lazy(() => workoutSchema);
|
|
760
784
|
var getV1WorkoutsWorkoutid404Schema = z22.any();
|
|
761
|
-
var getV1WorkoutsWorkoutidQueryResponseSchema = z22.lazy(() => getV1WorkoutsWorkoutid200Schema);
|
|
762
785
|
|
|
763
786
|
// src/generated/client/schemas/postRoutineFolderRequestBodySchema.ts
|
|
764
787
|
import { z as z23 } from "zod";
|
|
765
788
|
var postRoutineFolderRequestBodySchema = z23.object({
|
|
766
|
-
routine_folder: z23.object({
|
|
767
|
-
title: z23.string().describe("The title of the routine folder.")
|
|
768
|
-
})
|
|
789
|
+
"routine_folder": z23.optional(z23.object({
|
|
790
|
+
"title": z23.optional(z23.string().describe("The title of the routine folder."))
|
|
791
|
+
}))
|
|
769
792
|
});
|
|
770
793
|
|
|
771
794
|
// src/generated/client/schemas/postRoutinesRequestSetSchema.ts
|
|
772
795
|
import { z as z24 } from "zod";
|
|
773
796
|
var postRoutinesRequestSetSchema = z24.object({
|
|
774
|
-
type: z24.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")
|
|
775
|
-
weight_kg: z24.number().describe("The weight in kilograms.").
|
|
776
|
-
reps: z24.number().int().describe("The number of repetitions.").
|
|
777
|
-
distance_meters: z24.number().int().describe("The distance in meters.").
|
|
778
|
-
duration_seconds: z24.number().int().describe("The duration in seconds.").
|
|
779
|
-
custom_metric: z24.number().describe("A custom metric for the set. Currently used for steps and floors.").
|
|
780
|
-
rep_range: z24.object({
|
|
781
|
-
start: z24.number().describe("Starting rep count for the range").
|
|
782
|
-
end: z24.number().describe("Ending rep count for the range").
|
|
783
|
-
}).describe("Range of reps for the set, if applicable").
|
|
797
|
+
"type": z24.optional(z24.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")),
|
|
798
|
+
"weight_kg": z24.number().describe("The weight in kilograms.").nullish(),
|
|
799
|
+
"reps": z24.number().int().describe("The number of repetitions.").nullish(),
|
|
800
|
+
"distance_meters": z24.number().int().describe("The distance in meters.").nullish(),
|
|
801
|
+
"duration_seconds": z24.number().int().describe("The duration in seconds.").nullish(),
|
|
802
|
+
"custom_metric": z24.number().describe("A custom metric for the set. Currently used for steps and floors.").nullish(),
|
|
803
|
+
"rep_range": z24.object({
|
|
804
|
+
"start": z24.number().describe("Starting rep count for the range").nullish(),
|
|
805
|
+
"end": z24.number().describe("Ending rep count for the range").nullish()
|
|
806
|
+
}).describe("Range of reps for the set, if applicable").nullish()
|
|
784
807
|
});
|
|
785
808
|
|
|
786
809
|
// src/generated/client/schemas/postRoutinesRequestExerciseSchema.ts
|
|
787
810
|
import { z as z25 } from "zod";
|
|
788
811
|
var postRoutinesRequestExerciseSchema = z25.object({
|
|
789
|
-
exercise_template_id: z25.string().describe("The ID of the exercise template.")
|
|
790
|
-
superset_id: z25.number().int().describe("The ID of the superset.").
|
|
791
|
-
rest_seconds: z25.number().int().describe("The rest time in seconds.").
|
|
792
|
-
notes: z25.string().describe("Additional notes for the exercise.").
|
|
793
|
-
sets: z25.array(z25.lazy(() => postRoutinesRequestSetSchema))
|
|
812
|
+
"exercise_template_id": z25.optional(z25.string().describe("The ID of the exercise template.")),
|
|
813
|
+
"superset_id": z25.number().int().describe("The ID of the superset.").nullish(),
|
|
814
|
+
"rest_seconds": z25.number().int().describe("The rest time in seconds.").nullish(),
|
|
815
|
+
"notes": z25.string().describe("Additional notes for the exercise.").nullish(),
|
|
816
|
+
"sets": z25.optional(z25.array(z25.lazy(() => postRoutinesRequestSetSchema)))
|
|
794
817
|
});
|
|
795
818
|
|
|
796
819
|
// src/generated/client/schemas/postRoutinesRequestBodySchema.ts
|
|
797
820
|
import { z as z26 } from "zod";
|
|
798
821
|
var postRoutinesRequestBodySchema = z26.object({
|
|
799
|
-
routine: z26.object({
|
|
800
|
-
title: z26.string().describe("The title of the routine.")
|
|
801
|
-
folder_id: z26.number().describe('The folder id the routine should be added to. Pass null to insert the routine into default "My Routines" folder').
|
|
802
|
-
notes: z26.string().describe("Additional notes for the routine.")
|
|
803
|
-
exercises: z26.array(z26.lazy(() => postRoutinesRequestExerciseSchema))
|
|
804
|
-
})
|
|
822
|
+
"routine": z26.optional(z26.object({
|
|
823
|
+
"title": z26.optional(z26.string().describe("The title of the routine.")),
|
|
824
|
+
"folder_id": z26.number().describe('The folder id the routine should be added to. Pass null to insert the routine into default "My Routines" folder').nullish(),
|
|
825
|
+
"notes": z26.optional(z26.string().describe("Additional notes for the routine.")),
|
|
826
|
+
"exercises": z26.optional(z26.array(z26.lazy(() => postRoutinesRequestExerciseSchema)))
|
|
827
|
+
}))
|
|
805
828
|
});
|
|
806
829
|
|
|
807
830
|
// src/generated/client/schemas/postV1RoutineFoldersSchema.ts
|
|
@@ -809,33 +832,27 @@ import { z as z27 } from "zod";
|
|
|
809
832
|
var postV1RoutineFoldersHeaderParamsSchema = z27.object({
|
|
810
833
|
"api-key": z27.string().uuid()
|
|
811
834
|
});
|
|
812
|
-
var postV1RoutineFolders201Schema = z27.lazy(() => routineFolderSchema);
|
|
813
835
|
var postV1RoutineFolders400Schema = z27.object({
|
|
814
|
-
error: z27.string().describe("Error message")
|
|
836
|
+
"error": z27.optional(z27.string().describe("Error message"))
|
|
815
837
|
});
|
|
816
|
-
var postV1RoutineFoldersMutationRequestSchema = z27.lazy(() => postRoutineFolderRequestBodySchema);
|
|
817
|
-
var postV1RoutineFoldersMutationResponseSchema = z27.lazy(() => postV1RoutineFolders201Schema);
|
|
818
838
|
|
|
819
839
|
// src/generated/client/schemas/postV1RoutinesSchema.ts
|
|
820
840
|
import { z as z28 } from "zod";
|
|
821
841
|
var postV1RoutinesHeaderParamsSchema = z28.object({
|
|
822
842
|
"api-key": z28.string().uuid()
|
|
823
843
|
});
|
|
824
|
-
var postV1Routines201Schema = z28.lazy(() => routineSchema);
|
|
825
844
|
var postV1Routines400Schema = z28.object({
|
|
826
|
-
error: z28.string().describe("Error message")
|
|
845
|
+
"error": z28.optional(z28.string().describe("Error message"))
|
|
827
846
|
});
|
|
828
847
|
var postV1Routines403Schema = z28.object({
|
|
829
|
-
error: z28.string().describe("Error message")
|
|
848
|
+
"error": z28.optional(z28.string().describe("Error message"))
|
|
830
849
|
});
|
|
831
|
-
var postV1RoutinesMutationRequestSchema = z28.lazy(() => postRoutinesRequestBodySchema);
|
|
832
|
-
var postV1RoutinesMutationResponseSchema = z28.lazy(() => postV1Routines201Schema);
|
|
833
850
|
|
|
834
851
|
// src/generated/client/schemas/webhookRequestBodySchema.ts
|
|
835
852
|
import { z as z29 } from "zod";
|
|
836
853
|
var webhookRequestBodySchema = z29.object({
|
|
837
|
-
authToken: z29.string().describe("The auth token that will be send as Authorization header in the webhook.")
|
|
838
|
-
url: z29.string().describe("The webhook URL.")
|
|
854
|
+
"authToken": z29.optional(z29.string().describe("The auth token that will be send as Authorization header in the webhook.")),
|
|
855
|
+
"url": z29.optional(z29.string().describe("The webhook URL."))
|
|
839
856
|
});
|
|
840
857
|
|
|
841
858
|
// src/generated/client/schemas/postV1WebhookSubscriptionSchema.ts
|
|
@@ -845,43 +862,41 @@ var postV1WebhookSubscriptionHeaderParamsSchema = z30.object({
|
|
|
845
862
|
});
|
|
846
863
|
var postV1WebhookSubscription201Schema = z30.any();
|
|
847
864
|
var postV1WebhookSubscription400Schema = z30.object({
|
|
848
|
-
error: z30.string().describe("Error message")
|
|
865
|
+
"error": z30.optional(z30.string().describe("Error message"))
|
|
849
866
|
});
|
|
850
|
-
var postV1WebhookSubscriptionMutationRequestSchema = z30.lazy(() => webhookRequestBodySchema);
|
|
851
|
-
var postV1WebhookSubscriptionMutationResponseSchema = z30.lazy(() => postV1WebhookSubscription201Schema);
|
|
852
867
|
|
|
853
868
|
// src/generated/client/schemas/postWorkoutsRequestSetSchema.ts
|
|
854
869
|
import { z as z31 } from "zod";
|
|
855
870
|
var postWorkoutsRequestSetSchema = z31.object({
|
|
856
|
-
type: z31.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")
|
|
857
|
-
weight_kg: z31.number().describe("The weight in kilograms.").
|
|
858
|
-
reps: z31.number().int().describe("The number of repetitions.").
|
|
859
|
-
distance_meters: z31.number().int().describe("The distance in meters.").
|
|
860
|
-
duration_seconds: z31.number().int().describe("The duration in seconds.").
|
|
861
|
-
custom_metric: z31.number().describe("A custom metric for the set. Currently used for steps and floors.").
|
|
862
|
-
rpe: z31.union([z31.literal(6), z31.literal(7), z31.literal(7.5), z31.literal(8), z31.literal(8.5), z31.literal(9), z31.literal(9.5), z31.literal(10)]).describe("The Rating of Perceived Exertion (RPE).").
|
|
871
|
+
"type": z31.optional(z31.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")),
|
|
872
|
+
"weight_kg": z31.number().describe("The weight in kilograms.").nullish(),
|
|
873
|
+
"reps": z31.number().int().describe("The number of repetitions.").nullish(),
|
|
874
|
+
"distance_meters": z31.number().int().describe("The distance in meters.").nullish(),
|
|
875
|
+
"duration_seconds": z31.number().int().describe("The duration in seconds.").nullish(),
|
|
876
|
+
"custom_metric": z31.number().describe("A custom metric for the set. Currently used for steps and floors.").nullish(),
|
|
877
|
+
"rpe": z31.union([z31.literal(6), z31.literal(7), z31.literal(7.5), z31.literal(8), z31.literal(8.5), z31.literal(9), z31.literal(9.5), z31.literal(10)]).describe("The Rating of Perceived Exertion (RPE).").nullish()
|
|
863
878
|
});
|
|
864
879
|
|
|
865
880
|
// src/generated/client/schemas/postWorkoutsRequestExerciseSchema.ts
|
|
866
881
|
import { z as z32 } from "zod";
|
|
867
882
|
var postWorkoutsRequestExerciseSchema = z32.object({
|
|
868
|
-
exercise_template_id: z32.string().describe("The ID of the exercise template.")
|
|
869
|
-
superset_id: z32.number().int().describe("The ID of the superset.").
|
|
870
|
-
notes: z32.string().describe("Additional notes for the exercise.").
|
|
871
|
-
sets: z32.array(z32.lazy(() => postWorkoutsRequestSetSchema))
|
|
883
|
+
"exercise_template_id": z32.optional(z32.string().describe("The ID of the exercise template.")),
|
|
884
|
+
"superset_id": z32.number().int().describe("The ID of the superset.").nullish(),
|
|
885
|
+
"notes": z32.string().describe("Additional notes for the exercise.").nullish(),
|
|
886
|
+
"sets": z32.optional(z32.array(z32.lazy(() => postWorkoutsRequestSetSchema)))
|
|
872
887
|
});
|
|
873
888
|
|
|
874
889
|
// src/generated/client/schemas/postWorkoutsRequestBodySchema.ts
|
|
875
890
|
import { z as z33 } from "zod";
|
|
876
891
|
var postWorkoutsRequestBodySchema = z33.object({
|
|
877
|
-
workout: z33.object({
|
|
878
|
-
title: z33.string().describe("The title of the workout.")
|
|
879
|
-
description: z33.string().describe("A description for the workout workout.").
|
|
880
|
-
start_time: z33.string().describe("The time the workout started.")
|
|
881
|
-
end_time: z33.string().describe("The time the workout ended.")
|
|
882
|
-
is_private: z33.boolean().describe("A boolean indicating if the workout is private.")
|
|
883
|
-
exercises: z33.array(z33.lazy(() => postWorkoutsRequestExerciseSchema))
|
|
884
|
-
})
|
|
892
|
+
"workout": z33.optional(z33.object({
|
|
893
|
+
"title": z33.optional(z33.string().describe("The title of the workout.")),
|
|
894
|
+
"description": z33.string().describe("A description for the workout workout.").nullish(),
|
|
895
|
+
"start_time": z33.optional(z33.string().describe("The time the workout started.")),
|
|
896
|
+
"end_time": z33.optional(z33.string().describe("The time the workout ended.")),
|
|
897
|
+
"is_private": z33.optional(z33.boolean().describe("A boolean indicating if the workout is private.")),
|
|
898
|
+
"exercises": z33.optional(z33.array(z33.lazy(() => postWorkoutsRequestExerciseSchema)))
|
|
899
|
+
}))
|
|
885
900
|
});
|
|
886
901
|
|
|
887
902
|
// src/generated/client/schemas/postV1WorkoutsSchema.ts
|
|
@@ -889,80 +904,71 @@ import { z as z34 } from "zod";
|
|
|
889
904
|
var postV1WorkoutsHeaderParamsSchema = z34.object({
|
|
890
905
|
"api-key": z34.string().uuid()
|
|
891
906
|
});
|
|
892
|
-
var postV1Workouts201Schema = z34.lazy(() => workoutSchema);
|
|
893
907
|
var postV1Workouts400Schema = z34.object({
|
|
894
|
-
error: z34.string().describe("Error message")
|
|
908
|
+
"error": z34.optional(z34.string().describe("Error message"))
|
|
895
909
|
});
|
|
896
|
-
var postV1WorkoutsMutationRequestSchema = z34.lazy(() => postWorkoutsRequestBodySchema);
|
|
897
|
-
var postV1WorkoutsMutationResponseSchema = z34.lazy(() => postV1Workouts201Schema);
|
|
898
910
|
|
|
899
911
|
// src/generated/client/schemas/putRoutinesRequestSetSchema.ts
|
|
900
912
|
import { z as z35 } from "zod";
|
|
901
913
|
var putRoutinesRequestSetSchema = z35.object({
|
|
902
|
-
type: z35.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")
|
|
903
|
-
weight_kg: z35.number().describe("The weight in kilograms.").
|
|
904
|
-
reps: z35.number().int().describe("The number of repetitions.").
|
|
905
|
-
distance_meters: z35.number().int().describe("The distance in meters.").
|
|
906
|
-
duration_seconds: z35.number().int().describe("The duration in seconds.").
|
|
907
|
-
custom_metric: z35.number().describe("A custom metric for the set. Currently used for steps and floors.").
|
|
908
|
-
rep_range: z35.object({
|
|
909
|
-
start: z35.number().describe("Starting rep count for the range").
|
|
910
|
-
end: z35.number().describe("Ending rep count for the range").
|
|
911
|
-
}).describe("Range of reps for the set, if applicable").
|
|
914
|
+
"type": z35.optional(z35.enum(["warmup", "normal", "failure", "dropset"]).describe("The type of the set.")),
|
|
915
|
+
"weight_kg": z35.number().describe("The weight in kilograms.").nullish(),
|
|
916
|
+
"reps": z35.number().int().describe("The number of repetitions.").nullish(),
|
|
917
|
+
"distance_meters": z35.number().int().describe("The distance in meters.").nullish(),
|
|
918
|
+
"duration_seconds": z35.number().int().describe("The duration in seconds.").nullish(),
|
|
919
|
+
"custom_metric": z35.number().describe("A custom metric for the set. Currently used for steps and floors.").nullish(),
|
|
920
|
+
"rep_range": z35.object({
|
|
921
|
+
"start": z35.number().describe("Starting rep count for the range").nullish(),
|
|
922
|
+
"end": z35.number().describe("Ending rep count for the range").nullish()
|
|
923
|
+
}).describe("Range of reps for the set, if applicable").nullish()
|
|
912
924
|
});
|
|
913
925
|
|
|
914
926
|
// src/generated/client/schemas/putRoutinesRequestExerciseSchema.ts
|
|
915
927
|
import { z as z36 } from "zod";
|
|
916
928
|
var putRoutinesRequestExerciseSchema = z36.object({
|
|
917
|
-
exercise_template_id: z36.string().describe("The ID of the exercise template.")
|
|
918
|
-
superset_id: z36.number().int().describe("The ID of the superset.").
|
|
919
|
-
rest_seconds: z36.number().int().describe("The rest time in seconds.").
|
|
920
|
-
notes: z36.string().describe("Additional notes for the exercise.").
|
|
921
|
-
sets: z36.array(z36.lazy(() => putRoutinesRequestSetSchema))
|
|
929
|
+
"exercise_template_id": z36.optional(z36.string().describe("The ID of the exercise template.")),
|
|
930
|
+
"superset_id": z36.number().int().describe("The ID of the superset.").nullish(),
|
|
931
|
+
"rest_seconds": z36.number().int().describe("The rest time in seconds.").nullish(),
|
|
932
|
+
"notes": z36.string().describe("Additional notes for the exercise.").nullish(),
|
|
933
|
+
"sets": z36.optional(z36.array(z36.lazy(() => putRoutinesRequestSetSchema)))
|
|
922
934
|
});
|
|
923
935
|
|
|
924
936
|
// src/generated/client/schemas/putRoutinesRequestBodySchema.ts
|
|
925
937
|
import { z as z37 } from "zod";
|
|
926
938
|
var putRoutinesRequestBodySchema = z37.object({
|
|
927
|
-
routine: z37.object({
|
|
928
|
-
title: z37.string().describe("The title of the routine.")
|
|
929
|
-
notes: z37.string().describe("Additional notes for the routine.").
|
|
930
|
-
exercises: z37.array(z37.lazy(() => putRoutinesRequestExerciseSchema))
|
|
931
|
-
})
|
|
939
|
+
"routine": z37.optional(z37.object({
|
|
940
|
+
"title": z37.optional(z37.string().describe("The title of the routine.")),
|
|
941
|
+
"notes": z37.string().describe("Additional notes for the routine.").nullish(),
|
|
942
|
+
"exercises": z37.optional(z37.array(z37.lazy(() => putRoutinesRequestExerciseSchema)))
|
|
943
|
+
}))
|
|
932
944
|
});
|
|
933
945
|
|
|
934
946
|
// src/generated/client/schemas/putV1RoutinesRoutineidSchema.ts
|
|
935
947
|
import { z as z38 } from "zod";
|
|
936
948
|
var putV1RoutinesRoutineidPathParamsSchema = z38.object({
|
|
937
|
-
routineId: z38.any()
|
|
949
|
+
"routineId": z38.any()
|
|
938
950
|
});
|
|
939
951
|
var putV1RoutinesRoutineidHeaderParamsSchema = z38.object({
|
|
940
952
|
"api-key": z38.string().uuid()
|
|
941
953
|
});
|
|
942
|
-
var putV1RoutinesRoutineid200Schema = z38.lazy(() => routineSchema);
|
|
943
954
|
var putV1RoutinesRoutineid400Schema = z38.object({
|
|
944
|
-
error: z38.string().describe("Error message")
|
|
955
|
+
"error": z38.optional(z38.string().describe("Error message"))
|
|
945
956
|
});
|
|
946
957
|
var putV1RoutinesRoutineid404Schema = z38.object({
|
|
947
|
-
error: z38.string().describe("Error message")
|
|
958
|
+
"error": z38.optional(z38.string().describe("Error message"))
|
|
948
959
|
});
|
|
949
|
-
var putV1RoutinesRoutineidMutationRequestSchema = z38.lazy(() => putRoutinesRequestBodySchema);
|
|
950
|
-
var putV1RoutinesRoutineidMutationResponseSchema = z38.lazy(() => putV1RoutinesRoutineid200Schema);
|
|
951
960
|
|
|
952
961
|
// src/generated/client/schemas/putV1WorkoutsWorkoutidSchema.ts
|
|
953
962
|
import { z as z39 } from "zod";
|
|
954
963
|
var putV1WorkoutsWorkoutidPathParamsSchema = z39.object({
|
|
955
|
-
workoutId: z39.any()
|
|
964
|
+
"workoutId": z39.any()
|
|
956
965
|
});
|
|
957
966
|
var putV1WorkoutsWorkoutidHeaderParamsSchema = z39.object({
|
|
958
967
|
"api-key": z39.string().uuid()
|
|
959
968
|
});
|
|
960
|
-
var putV1WorkoutsWorkoutid200Schema = z39.lazy(() => workoutSchema);
|
|
961
969
|
var putV1WorkoutsWorkoutid400Schema = z39.object({
|
|
962
|
-
error: z39.string().describe("Error message")
|
|
970
|
+
"error": z39.optional(z39.string().describe("Error message"))
|
|
963
971
|
});
|
|
964
|
-
var putV1WorkoutsWorkoutidMutationRequestSchema = z39.lazy(() => postWorkoutsRequestBodySchema);
|
|
965
|
-
var putV1WorkoutsWorkoutidMutationResponseSchema = z39.lazy(() => putV1WorkoutsWorkoutid200Schema);
|
|
966
972
|
|
|
967
973
|
// src/tools/webhooks.ts
|
|
968
974
|
var webhookUrlSchema = z40.string().url().refine(
|
|
@@ -990,13 +996,18 @@ var webhookUrlSchema = z40.string().url().refine(
|
|
|
990
996
|
message: "Webhook URL cannot be localhost or loopback address"
|
|
991
997
|
}
|
|
992
998
|
);
|
|
993
|
-
function registerWebhookTools(
|
|
994
|
-
|
|
999
|
+
function registerWebhookTools(server, hevyClient) {
|
|
1000
|
+
server.tool(
|
|
995
1001
|
"get-webhook-subscription",
|
|
996
1002
|
"Get the current webhook subscription for this account. Returns the webhook URL and auth token if a subscription exists.",
|
|
997
1003
|
{},
|
|
998
1004
|
withErrorHandling(async () => {
|
|
999
|
-
|
|
1005
|
+
if (!hevyClient) {
|
|
1006
|
+
throw new Error(
|
|
1007
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
const data = await hevyClient.getWebhookSubscription();
|
|
1000
1011
|
if (!data) {
|
|
1001
1012
|
return createEmptyResponse(
|
|
1002
1013
|
"No webhook subscription found for this account"
|
|
@@ -1005,7 +1016,7 @@ function registerWebhookTools(server2, hevyClient2) {
|
|
|
1005
1016
|
return createJsonResponse(data);
|
|
1006
1017
|
}, "get-webhook-subscription")
|
|
1007
1018
|
);
|
|
1008
|
-
|
|
1019
|
+
server.tool(
|
|
1009
1020
|
"create-webhook-subscription",
|
|
1010
1021
|
"Create a new webhook subscription for this account. The webhook will receive POST requests when workouts are created. Your endpoint must respond with 200 OK within 5 seconds.",
|
|
1011
1022
|
{
|
|
@@ -1017,11 +1028,16 @@ function registerWebhookTools(server2, hevyClient2) {
|
|
|
1017
1028
|
)
|
|
1018
1029
|
},
|
|
1019
1030
|
withErrorHandling(async ({ url, authToken }) => {
|
|
1031
|
+
if (!hevyClient) {
|
|
1032
|
+
throw new Error(
|
|
1033
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1020
1036
|
const requestBody = webhookRequestBodySchema.parse({
|
|
1021
1037
|
url,
|
|
1022
1038
|
authToken
|
|
1023
1039
|
});
|
|
1024
|
-
const data = await
|
|
1040
|
+
const data = await hevyClient.createWebhookSubscription(requestBody);
|
|
1025
1041
|
if (!data) {
|
|
1026
1042
|
return createEmptyResponse(
|
|
1027
1043
|
"Failed to create webhook subscription - please check your URL and try again"
|
|
@@ -1030,12 +1046,17 @@ function registerWebhookTools(server2, hevyClient2) {
|
|
|
1030
1046
|
return createJsonResponse(data);
|
|
1031
1047
|
}, "create-webhook-subscription")
|
|
1032
1048
|
);
|
|
1033
|
-
|
|
1049
|
+
server.tool(
|
|
1034
1050
|
"delete-webhook-subscription",
|
|
1035
1051
|
"Delete the current webhook subscription for this account. This will stop all webhook notifications.",
|
|
1036
1052
|
{},
|
|
1037
1053
|
withErrorHandling(async () => {
|
|
1038
|
-
|
|
1054
|
+
if (!hevyClient) {
|
|
1055
|
+
throw new Error(
|
|
1056
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
const data = await hevyClient.deleteWebhookSubscription();
|
|
1039
1060
|
if (!data) {
|
|
1040
1061
|
return createEmptyResponse(
|
|
1041
1062
|
"Failed to delete webhook subscription - no subscription may exist or there was a server error"
|
|
@@ -1048,8 +1069,8 @@ function registerWebhookTools(server2, hevyClient2) {
|
|
|
1048
1069
|
|
|
1049
1070
|
// src/tools/workouts.ts
|
|
1050
1071
|
import { z as z41 } from "zod";
|
|
1051
|
-
function registerWorkoutTools(
|
|
1052
|
-
|
|
1072
|
+
function registerWorkoutTools(server, hevyClient) {
|
|
1073
|
+
server.tool(
|
|
1053
1074
|
"get-workouts",
|
|
1054
1075
|
"Get a paginated list of workouts. Returns workout details including title, description, start/end times, and exercises performed. Results are ordered from newest to oldest.",
|
|
1055
1076
|
{
|
|
@@ -1057,7 +1078,12 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1057
1078
|
pageSize: z41.coerce.number().int().gte(1).lte(10).default(5)
|
|
1058
1079
|
},
|
|
1059
1080
|
withErrorHandling(async ({ page, pageSize }) => {
|
|
1060
|
-
|
|
1081
|
+
if (!hevyClient) {
|
|
1082
|
+
throw new Error(
|
|
1083
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
const data = await hevyClient.getWorkouts({
|
|
1061
1087
|
page,
|
|
1062
1088
|
pageSize
|
|
1063
1089
|
});
|
|
@@ -1070,14 +1096,19 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1070
1096
|
return createJsonResponse(workouts);
|
|
1071
1097
|
}, "get-workouts")
|
|
1072
1098
|
);
|
|
1073
|
-
|
|
1099
|
+
server.tool(
|
|
1074
1100
|
"get-workout",
|
|
1075
1101
|
"Get complete details of a specific workout by ID. Returns all workout information including title, description, start/end times, and detailed exercise data.",
|
|
1076
1102
|
{
|
|
1077
1103
|
workoutId: z41.string().min(1)
|
|
1078
1104
|
},
|
|
1079
1105
|
withErrorHandling(async ({ workoutId }) => {
|
|
1080
|
-
|
|
1106
|
+
if (!hevyClient) {
|
|
1107
|
+
throw new Error(
|
|
1108
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
const data = await hevyClient.getWorkout(workoutId);
|
|
1081
1112
|
if (!data) {
|
|
1082
1113
|
return createEmptyResponse(`Workout with ID ${workoutId} not found`);
|
|
1083
1114
|
}
|
|
@@ -1085,17 +1116,22 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1085
1116
|
return createJsonResponse(workout);
|
|
1086
1117
|
}, "get-workout")
|
|
1087
1118
|
);
|
|
1088
|
-
|
|
1119
|
+
server.tool(
|
|
1089
1120
|
"get-workout-count",
|
|
1090
1121
|
"Get the total number of workouts on the account. Useful for pagination or statistics.",
|
|
1091
1122
|
{},
|
|
1092
1123
|
withErrorHandling(async () => {
|
|
1093
|
-
|
|
1124
|
+
if (!hevyClient) {
|
|
1125
|
+
throw new Error(
|
|
1126
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
const data = await hevyClient.getWorkoutCount();
|
|
1094
1130
|
const count = data ? data.workoutCount || 0 : 0;
|
|
1095
1131
|
return createJsonResponse({ count });
|
|
1096
1132
|
}, "get-workout-count")
|
|
1097
1133
|
);
|
|
1098
|
-
|
|
1134
|
+
server.tool(
|
|
1099
1135
|
"get-workout-events",
|
|
1100
1136
|
"Retrieve a paged list of workout events (updates or deletes) since a given date. Events are ordered from newest to oldest. The intention is to allow clients to keep their local cache of workouts up to date without having to fetch the entire list of workouts.",
|
|
1101
1137
|
{
|
|
@@ -1104,7 +1140,12 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1104
1140
|
since: z41.string().default("1970-01-01T00:00:00Z")
|
|
1105
1141
|
},
|
|
1106
1142
|
withErrorHandling(async ({ page, pageSize, since }) => {
|
|
1107
|
-
|
|
1143
|
+
if (!hevyClient) {
|
|
1144
|
+
throw new Error(
|
|
1145
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
const data = await hevyClient.getWorkoutEvents({
|
|
1108
1149
|
page,
|
|
1109
1150
|
pageSize,
|
|
1110
1151
|
since
|
|
@@ -1118,7 +1159,7 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1118
1159
|
return createJsonResponse(events);
|
|
1119
1160
|
}, "get-workout-events")
|
|
1120
1161
|
);
|
|
1121
|
-
|
|
1162
|
+
server.tool(
|
|
1122
1163
|
"create-workout",
|
|
1123
1164
|
"Create a new workout in your Hevy account. Requires title, start/end times, and at least one exercise with sets. Returns the complete workout details upon successful creation including the newly assigned workout ID.",
|
|
1124
1165
|
{
|
|
@@ -1155,6 +1196,11 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1155
1196
|
isPrivate,
|
|
1156
1197
|
exercises
|
|
1157
1198
|
}) => {
|
|
1199
|
+
if (!hevyClient) {
|
|
1200
|
+
throw new Error(
|
|
1201
|
+
"API client not initialized. Please provide HEVY_API_KEY."
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1158
1204
|
const requestBody = {
|
|
1159
1205
|
workout: {
|
|
1160
1206
|
title,
|
|
@@ -1178,7 +1224,7 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1178
1224
|
}))
|
|
1179
1225
|
}
|
|
1180
1226
|
};
|
|
1181
|
-
const data = await
|
|
1227
|
+
const data = await hevyClient.createWorkout(requestBody);
|
|
1182
1228
|
if (!data) {
|
|
1183
1229
|
return createEmptyResponse(
|
|
1184
1230
|
"Failed to create workout: Server returned no data"
|
|
@@ -1193,7 +1239,7 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1193
1239
|
"create-workout"
|
|
1194
1240
|
)
|
|
1195
1241
|
);
|
|
1196
|
-
|
|
1242
|
+
server.tool(
|
|
1197
1243
|
"update-workout",
|
|
1198
1244
|
"Update an existing workout by ID. You can modify the title, description, start/end times, privacy setting, and exercise data. Returns the updated workout with all changes applied.",
|
|
1199
1245
|
{
|
|
@@ -1255,7 +1301,7 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1255
1301
|
}))
|
|
1256
1302
|
}
|
|
1257
1303
|
};
|
|
1258
|
-
const data = await
|
|
1304
|
+
const data = await hevyClient.updateWorkout(workoutId, requestBody);
|
|
1259
1305
|
if (!data) {
|
|
1260
1306
|
return createEmptyResponse(
|
|
1261
1307
|
`Failed to update workout with ID ${workoutId}`
|
|
@@ -1274,7 +1320,7 @@ function registerWorkoutTools(server2, hevyClient2) {
|
|
|
1274
1320
|
|
|
1275
1321
|
// src/utils/config.ts
|
|
1276
1322
|
function parseConfig(argv, env) {
|
|
1277
|
-
let
|
|
1323
|
+
let apiKey = "";
|
|
1278
1324
|
const apiKeyArgPatterns = [
|
|
1279
1325
|
/^--hevy-api-key=(.+)$/i,
|
|
1280
1326
|
/^--hevyApiKey=(.+)$/i,
|
|
@@ -1284,33 +1330,23 @@ function parseConfig(argv, env) {
|
|
|
1284
1330
|
for (const pattern of apiKeyArgPatterns) {
|
|
1285
1331
|
const m = raw.match(pattern);
|
|
1286
1332
|
if (m) {
|
|
1287
|
-
|
|
1333
|
+
apiKey = m[1];
|
|
1288
1334
|
break;
|
|
1289
1335
|
}
|
|
1290
1336
|
}
|
|
1291
|
-
if (
|
|
1337
|
+
if (apiKey) break;
|
|
1292
1338
|
}
|
|
1293
|
-
if (!
|
|
1294
|
-
|
|
1339
|
+
if (!apiKey) {
|
|
1340
|
+
apiKey = env.HEVY_API_KEY || "";
|
|
1295
1341
|
}
|
|
1296
|
-
const transportMode = argv.includes("--http") || env.MCP_TRANSPORT === "http" ? "http" : "stdio";
|
|
1297
|
-
const httpPort = Number.parseInt(env.MCP_HTTP_PORT || "3000", 10);
|
|
1298
|
-
const httpHost = env.MCP_HTTP_HOST || "127.0.0.1";
|
|
1299
|
-
const enableDnsRebindingProtection = env.MCP_DNS_REBINDING_PROTECTION === "true";
|
|
1300
|
-
const allowedHosts = env.MCP_ALLOWED_HOSTS?.split(",").map((h) => h.trim()).filter(Boolean) || ["127.0.0.1"];
|
|
1301
1342
|
return {
|
|
1302
|
-
apiKey
|
|
1303
|
-
transportMode,
|
|
1304
|
-
httpHost,
|
|
1305
|
-
httpPort,
|
|
1306
|
-
enableDnsRebindingProtection,
|
|
1307
|
-
allowedHosts
|
|
1343
|
+
apiKey
|
|
1308
1344
|
};
|
|
1309
1345
|
}
|
|
1310
|
-
function assertApiKey(
|
|
1311
|
-
if (!
|
|
1346
|
+
function assertApiKey(apiKey) {
|
|
1347
|
+
if (!apiKey) {
|
|
1312
1348
|
console.error(
|
|
1313
|
-
"Hevy API key is required. Provide via HEVY_API_KEY
|
|
1349
|
+
"Hevy API key is required. Provide it via the HEVY_API_KEY environment variable or the --hevy-api-key=YOUR_KEY command argument."
|
|
1314
1350
|
);
|
|
1315
1351
|
process.exit(1);
|
|
1316
1352
|
}
|
|
@@ -1322,318 +1358,235 @@ import axios from "axios";
|
|
|
1322
1358
|
// src/generated/client/api/deleteV1WebhookSubscription.ts
|
|
1323
1359
|
import fetch from "@kubb/plugin-client/clients/axios";
|
|
1324
1360
|
function getDeleteV1WebhookSubscriptionUrl() {
|
|
1325
|
-
|
|
1361
|
+
const res = { method: "DELETE", url: `/v1/webhook-subscription` };
|
|
1362
|
+
return res;
|
|
1326
1363
|
}
|
|
1327
1364
|
async function deleteV1WebhookSubscription(headers, config = {}) {
|
|
1328
1365
|
const { client: request = fetch, ...requestConfig } = config;
|
|
1329
|
-
const res = await request({
|
|
1330
|
-
method: "DELETE",
|
|
1331
|
-
url: getDeleteV1WebhookSubscriptionUrl().toString(),
|
|
1332
|
-
...requestConfig,
|
|
1333
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1334
|
-
});
|
|
1366
|
+
const res = await request({ method: "DELETE", url: getDeleteV1WebhookSubscriptionUrl().url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1335
1367
|
return res.data;
|
|
1336
1368
|
}
|
|
1337
1369
|
|
|
1338
1370
|
// src/generated/client/api/getV1ExerciseTemplates.ts
|
|
1339
1371
|
import fetch2 from "@kubb/plugin-client/clients/axios";
|
|
1340
1372
|
function getGetV1ExerciseTemplatesUrl() {
|
|
1341
|
-
|
|
1373
|
+
const res = { method: "GET", url: `/v1/exercise_templates` };
|
|
1374
|
+
return res;
|
|
1342
1375
|
}
|
|
1343
1376
|
async function getV1ExerciseTemplates(headers, params, config = {}) {
|
|
1344
1377
|
const { client: request = fetch2, ...requestConfig } = config;
|
|
1345
|
-
const res = await request({
|
|
1346
|
-
method: "GET",
|
|
1347
|
-
url: getGetV1ExerciseTemplatesUrl().toString(),
|
|
1348
|
-
params,
|
|
1349
|
-
...requestConfig,
|
|
1350
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1351
|
-
});
|
|
1378
|
+
const res = await request({ method: "GET", url: getGetV1ExerciseTemplatesUrl().url.toString(), params, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1352
1379
|
return res.data;
|
|
1353
1380
|
}
|
|
1354
1381
|
|
|
1355
1382
|
// src/generated/client/api/getV1ExerciseTemplatesExercisetemplateid.ts
|
|
1356
1383
|
import fetch3 from "@kubb/plugin-client/clients/axios";
|
|
1357
1384
|
function getGetV1ExerciseTemplatesExercisetemplateidUrl(exerciseTemplateId) {
|
|
1358
|
-
|
|
1385
|
+
const res = { method: "GET", url: `/v1/exercise_templates/${exerciseTemplateId}` };
|
|
1386
|
+
return res;
|
|
1359
1387
|
}
|
|
1360
1388
|
async function getV1ExerciseTemplatesExercisetemplateid(exerciseTemplateId, headers, config = {}) {
|
|
1361
1389
|
const { client: request = fetch3, ...requestConfig } = config;
|
|
1362
|
-
const res = await request({
|
|
1363
|
-
method: "GET",
|
|
1364
|
-
url: getGetV1ExerciseTemplatesExercisetemplateidUrl(exerciseTemplateId).toString(),
|
|
1365
|
-
...requestConfig,
|
|
1366
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1367
|
-
});
|
|
1390
|
+
const res = await request({ method: "GET", url: getGetV1ExerciseTemplatesExercisetemplateidUrl(exerciseTemplateId).url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1368
1391
|
return res.data;
|
|
1369
1392
|
}
|
|
1370
1393
|
|
|
1371
1394
|
// src/generated/client/api/getV1RoutineFolders.ts
|
|
1372
1395
|
import fetch4 from "@kubb/plugin-client/clients/axios";
|
|
1373
1396
|
function getGetV1RoutineFoldersUrl() {
|
|
1374
|
-
|
|
1397
|
+
const res = { method: "GET", url: `/v1/routine_folders` };
|
|
1398
|
+
return res;
|
|
1375
1399
|
}
|
|
1376
1400
|
async function getV1RoutineFolders(headers, params, config = {}) {
|
|
1377
1401
|
const { client: request = fetch4, ...requestConfig } = config;
|
|
1378
|
-
const res = await request({
|
|
1379
|
-
method: "GET",
|
|
1380
|
-
url: getGetV1RoutineFoldersUrl().toString(),
|
|
1381
|
-
params,
|
|
1382
|
-
...requestConfig,
|
|
1383
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1384
|
-
});
|
|
1402
|
+
const res = await request({ method: "GET", url: getGetV1RoutineFoldersUrl().url.toString(), params, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1385
1403
|
return res.data;
|
|
1386
1404
|
}
|
|
1387
1405
|
|
|
1388
1406
|
// src/generated/client/api/getV1RoutineFoldersFolderid.ts
|
|
1389
1407
|
import fetch5 from "@kubb/plugin-client/clients/axios";
|
|
1390
1408
|
function getGetV1RoutineFoldersFolderidUrl(folderId) {
|
|
1391
|
-
|
|
1409
|
+
const res = { method: "GET", url: `/v1/routine_folders/${folderId}` };
|
|
1410
|
+
return res;
|
|
1392
1411
|
}
|
|
1393
1412
|
async function getV1RoutineFoldersFolderid(folderId, headers, config = {}) {
|
|
1394
1413
|
const { client: request = fetch5, ...requestConfig } = config;
|
|
1395
|
-
const res = await request({
|
|
1396
|
-
method: "GET",
|
|
1397
|
-
url: getGetV1RoutineFoldersFolderidUrl(folderId).toString(),
|
|
1398
|
-
...requestConfig,
|
|
1399
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1400
|
-
});
|
|
1414
|
+
const res = await request({ method: "GET", url: getGetV1RoutineFoldersFolderidUrl(folderId).url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1401
1415
|
return res.data;
|
|
1402
1416
|
}
|
|
1403
1417
|
|
|
1404
1418
|
// src/generated/client/api/getV1Routines.ts
|
|
1405
1419
|
import fetch6 from "@kubb/plugin-client/clients/axios";
|
|
1406
1420
|
function getGetV1RoutinesUrl() {
|
|
1407
|
-
|
|
1421
|
+
const res = { method: "GET", url: `/v1/routines` };
|
|
1422
|
+
return res;
|
|
1408
1423
|
}
|
|
1409
1424
|
async function getV1Routines(headers, params, config = {}) {
|
|
1410
1425
|
const { client: request = fetch6, ...requestConfig } = config;
|
|
1411
|
-
const res = await request({
|
|
1412
|
-
method: "GET",
|
|
1413
|
-
url: getGetV1RoutinesUrl().toString(),
|
|
1414
|
-
params,
|
|
1415
|
-
...requestConfig,
|
|
1416
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1417
|
-
});
|
|
1426
|
+
const res = await request({ method: "GET", url: getGetV1RoutinesUrl().url.toString(), params, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1418
1427
|
return res.data;
|
|
1419
1428
|
}
|
|
1420
1429
|
|
|
1421
1430
|
// src/generated/client/api/getV1RoutinesRoutineid.ts
|
|
1422
1431
|
import fetch7 from "@kubb/plugin-client/clients/axios";
|
|
1423
1432
|
function getGetV1RoutinesRoutineidUrl(routineId) {
|
|
1424
|
-
|
|
1433
|
+
const res = { method: "GET", url: `/v1/routines/${routineId}` };
|
|
1434
|
+
return res;
|
|
1425
1435
|
}
|
|
1426
1436
|
async function getV1RoutinesRoutineid(routineId, headers, config = {}) {
|
|
1427
1437
|
const { client: request = fetch7, ...requestConfig } = config;
|
|
1428
|
-
const res = await request({
|
|
1429
|
-
method: "GET",
|
|
1430
|
-
url: getGetV1RoutinesRoutineidUrl(routineId).toString(),
|
|
1431
|
-
...requestConfig,
|
|
1432
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1433
|
-
});
|
|
1438
|
+
const res = await request({ method: "GET", url: getGetV1RoutinesRoutineidUrl(routineId).url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1434
1439
|
return res.data;
|
|
1435
1440
|
}
|
|
1436
1441
|
|
|
1437
1442
|
// src/generated/client/api/getV1WebhookSubscription.ts
|
|
1438
1443
|
import fetch8 from "@kubb/plugin-client/clients/axios";
|
|
1439
1444
|
function getGetV1WebhookSubscriptionUrl() {
|
|
1440
|
-
|
|
1445
|
+
const res = { method: "GET", url: `/v1/webhook-subscription` };
|
|
1446
|
+
return res;
|
|
1441
1447
|
}
|
|
1442
1448
|
async function getV1WebhookSubscription(headers, config = {}) {
|
|
1443
1449
|
const { client: request = fetch8, ...requestConfig } = config;
|
|
1444
|
-
const res = await request({
|
|
1445
|
-
method: "GET",
|
|
1446
|
-
url: getGetV1WebhookSubscriptionUrl().toString(),
|
|
1447
|
-
...requestConfig,
|
|
1448
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1449
|
-
});
|
|
1450
|
+
const res = await request({ method: "GET", url: getGetV1WebhookSubscriptionUrl().url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1450
1451
|
return res.data;
|
|
1451
1452
|
}
|
|
1452
1453
|
|
|
1453
1454
|
// src/generated/client/api/getV1Workouts.ts
|
|
1454
1455
|
import fetch9 from "@kubb/plugin-client/clients/axios";
|
|
1455
1456
|
function getGetV1WorkoutsUrl() {
|
|
1456
|
-
|
|
1457
|
+
const res = { method: "GET", url: `/v1/workouts` };
|
|
1458
|
+
return res;
|
|
1457
1459
|
}
|
|
1458
1460
|
async function getV1Workouts(headers, params, config = {}) {
|
|
1459
1461
|
const { client: request = fetch9, ...requestConfig } = config;
|
|
1460
|
-
const res = await request({
|
|
1461
|
-
method: "GET",
|
|
1462
|
-
url: getGetV1WorkoutsUrl().toString(),
|
|
1463
|
-
params,
|
|
1464
|
-
...requestConfig,
|
|
1465
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1466
|
-
});
|
|
1462
|
+
const res = await request({ method: "GET", url: getGetV1WorkoutsUrl().url.toString(), params, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1467
1463
|
return res.data;
|
|
1468
1464
|
}
|
|
1469
1465
|
|
|
1470
1466
|
// src/generated/client/api/getV1WorkoutsCount.ts
|
|
1471
1467
|
import fetch10 from "@kubb/plugin-client/clients/axios";
|
|
1472
1468
|
function getGetV1WorkoutsCountUrl() {
|
|
1473
|
-
|
|
1469
|
+
const res = { method: "GET", url: `/v1/workouts/count` };
|
|
1470
|
+
return res;
|
|
1474
1471
|
}
|
|
1475
1472
|
async function getV1WorkoutsCount(headers, config = {}) {
|
|
1476
1473
|
const { client: request = fetch10, ...requestConfig } = config;
|
|
1477
|
-
const res = await request({
|
|
1478
|
-
method: "GET",
|
|
1479
|
-
url: getGetV1WorkoutsCountUrl().toString(),
|
|
1480
|
-
...requestConfig,
|
|
1481
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1482
|
-
});
|
|
1474
|
+
const res = await request({ method: "GET", url: getGetV1WorkoutsCountUrl().url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1483
1475
|
return res.data;
|
|
1484
1476
|
}
|
|
1485
1477
|
|
|
1486
1478
|
// src/generated/client/api/getV1WorkoutsEvents.ts
|
|
1487
1479
|
import fetch11 from "@kubb/plugin-client/clients/axios";
|
|
1488
1480
|
function getGetV1WorkoutsEventsUrl() {
|
|
1489
|
-
|
|
1481
|
+
const res = { method: "GET", url: `/v1/workouts/events` };
|
|
1482
|
+
return res;
|
|
1490
1483
|
}
|
|
1491
1484
|
async function getV1WorkoutsEvents(headers, params, config = {}) {
|
|
1492
1485
|
const { client: request = fetch11, ...requestConfig } = config;
|
|
1493
|
-
const res = await request({
|
|
1494
|
-
method: "GET",
|
|
1495
|
-
url: getGetV1WorkoutsEventsUrl().toString(),
|
|
1496
|
-
params,
|
|
1497
|
-
...requestConfig,
|
|
1498
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1499
|
-
});
|
|
1486
|
+
const res = await request({ method: "GET", url: getGetV1WorkoutsEventsUrl().url.toString(), params, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1500
1487
|
return res.data;
|
|
1501
1488
|
}
|
|
1502
1489
|
|
|
1503
1490
|
// src/generated/client/api/getV1WorkoutsWorkoutid.ts
|
|
1504
1491
|
import fetch12 from "@kubb/plugin-client/clients/axios";
|
|
1505
1492
|
function getGetV1WorkoutsWorkoutidUrl(workoutId) {
|
|
1506
|
-
|
|
1493
|
+
const res = { method: "GET", url: `/v1/workouts/${workoutId}` };
|
|
1494
|
+
return res;
|
|
1507
1495
|
}
|
|
1508
1496
|
async function getV1WorkoutsWorkoutid(workoutId, headers, config = {}) {
|
|
1509
1497
|
const { client: request = fetch12, ...requestConfig } = config;
|
|
1510
|
-
const res = await request({
|
|
1511
|
-
method: "GET",
|
|
1512
|
-
url: getGetV1WorkoutsWorkoutidUrl(workoutId).toString(),
|
|
1513
|
-
...requestConfig,
|
|
1514
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1515
|
-
});
|
|
1498
|
+
const res = await request({ method: "GET", url: getGetV1WorkoutsWorkoutidUrl(workoutId).url.toString(), ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1516
1499
|
return res.data;
|
|
1517
1500
|
}
|
|
1518
1501
|
|
|
1519
1502
|
// src/generated/client/api/postV1RoutineFolders.ts
|
|
1520
1503
|
import fetch13 from "@kubb/plugin-client/clients/axios";
|
|
1521
1504
|
function getPostV1RoutineFoldersUrl() {
|
|
1522
|
-
|
|
1505
|
+
const res = { method: "POST", url: `/v1/routine_folders` };
|
|
1506
|
+
return res;
|
|
1523
1507
|
}
|
|
1524
1508
|
async function postV1RoutineFolders(headers, data, config = {}) {
|
|
1525
1509
|
const { client: request = fetch13, ...requestConfig } = config;
|
|
1526
1510
|
const requestData = data;
|
|
1527
|
-
const res = await request({
|
|
1528
|
-
method: "POST",
|
|
1529
|
-
url: getPostV1RoutineFoldersUrl().toString(),
|
|
1530
|
-
data: requestData,
|
|
1531
|
-
...requestConfig,
|
|
1532
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1533
|
-
});
|
|
1511
|
+
const res = await request({ method: "POST", url: getPostV1RoutineFoldersUrl().url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1534
1512
|
return res.data;
|
|
1535
1513
|
}
|
|
1536
1514
|
|
|
1537
1515
|
// src/generated/client/api/postV1Routines.ts
|
|
1538
1516
|
import fetch14 from "@kubb/plugin-client/clients/axios";
|
|
1539
1517
|
function getPostV1RoutinesUrl() {
|
|
1540
|
-
|
|
1518
|
+
const res = { method: "POST", url: `/v1/routines` };
|
|
1519
|
+
return res;
|
|
1541
1520
|
}
|
|
1542
1521
|
async function postV1Routines(headers, data, config = {}) {
|
|
1543
1522
|
const { client: request = fetch14, ...requestConfig } = config;
|
|
1544
1523
|
const requestData = data;
|
|
1545
|
-
const res = await request({
|
|
1546
|
-
method: "POST",
|
|
1547
|
-
url: getPostV1RoutinesUrl().toString(),
|
|
1548
|
-
data: requestData,
|
|
1549
|
-
...requestConfig,
|
|
1550
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1551
|
-
});
|
|
1524
|
+
const res = await request({ method: "POST", url: getPostV1RoutinesUrl().url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1552
1525
|
return res.data;
|
|
1553
1526
|
}
|
|
1554
1527
|
|
|
1555
1528
|
// src/generated/client/api/postV1WebhookSubscription.ts
|
|
1556
1529
|
import fetch15 from "@kubb/plugin-client/clients/axios";
|
|
1557
1530
|
function getPostV1WebhookSubscriptionUrl() {
|
|
1558
|
-
|
|
1531
|
+
const res = { method: "POST", url: `/v1/webhook-subscription` };
|
|
1532
|
+
return res;
|
|
1559
1533
|
}
|
|
1560
1534
|
async function postV1WebhookSubscription(headers, data, config = {}) {
|
|
1561
1535
|
const { client: request = fetch15, ...requestConfig } = config;
|
|
1562
1536
|
const requestData = data;
|
|
1563
|
-
const res = await request({
|
|
1564
|
-
method: "POST",
|
|
1565
|
-
url: getPostV1WebhookSubscriptionUrl().toString(),
|
|
1566
|
-
data: requestData,
|
|
1567
|
-
...requestConfig,
|
|
1568
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1569
|
-
});
|
|
1537
|
+
const res = await request({ method: "POST", url: getPostV1WebhookSubscriptionUrl().url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1570
1538
|
return res.data;
|
|
1571
1539
|
}
|
|
1572
1540
|
|
|
1573
1541
|
// src/generated/client/api/postV1Workouts.ts
|
|
1574
1542
|
import fetch16 from "@kubb/plugin-client/clients/axios";
|
|
1575
1543
|
function getPostV1WorkoutsUrl() {
|
|
1576
|
-
|
|
1544
|
+
const res = { method: "POST", url: `/v1/workouts` };
|
|
1545
|
+
return res;
|
|
1577
1546
|
}
|
|
1578
1547
|
async function postV1Workouts(headers, data, config = {}) {
|
|
1579
1548
|
const { client: request = fetch16, ...requestConfig } = config;
|
|
1580
1549
|
const requestData = data;
|
|
1581
|
-
const res = await request({
|
|
1582
|
-
method: "POST",
|
|
1583
|
-
url: getPostV1WorkoutsUrl().toString(),
|
|
1584
|
-
data: requestData,
|
|
1585
|
-
...requestConfig,
|
|
1586
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1587
|
-
});
|
|
1550
|
+
const res = await request({ method: "POST", url: getPostV1WorkoutsUrl().url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1588
1551
|
return res.data;
|
|
1589
1552
|
}
|
|
1590
1553
|
|
|
1591
1554
|
// src/generated/client/api/putV1RoutinesRoutineid.ts
|
|
1592
1555
|
import fetch17 from "@kubb/plugin-client/clients/axios";
|
|
1593
1556
|
function getPutV1RoutinesRoutineidUrl(routineId) {
|
|
1594
|
-
|
|
1557
|
+
const res = { method: "PUT", url: `/v1/routines/${routineId}` };
|
|
1558
|
+
return res;
|
|
1595
1559
|
}
|
|
1596
1560
|
async function putV1RoutinesRoutineid(routineId, headers, data, config = {}) {
|
|
1597
1561
|
const { client: request = fetch17, ...requestConfig } = config;
|
|
1598
1562
|
const requestData = data;
|
|
1599
|
-
const res = await request({
|
|
1600
|
-
method: "PUT",
|
|
1601
|
-
url: getPutV1RoutinesRoutineidUrl(routineId).toString(),
|
|
1602
|
-
data: requestData,
|
|
1603
|
-
...requestConfig,
|
|
1604
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1605
|
-
});
|
|
1563
|
+
const res = await request({ method: "PUT", url: getPutV1RoutinesRoutineidUrl(routineId).url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1606
1564
|
return res.data;
|
|
1607
1565
|
}
|
|
1608
1566
|
|
|
1609
1567
|
// src/generated/client/api/putV1WorkoutsWorkoutid.ts
|
|
1610
1568
|
import fetch18 from "@kubb/plugin-client/clients/axios";
|
|
1611
1569
|
function getPutV1WorkoutsWorkoutidUrl(workoutId) {
|
|
1612
|
-
|
|
1570
|
+
const res = { method: "PUT", url: `/v1/workouts/${workoutId}` };
|
|
1571
|
+
return res;
|
|
1613
1572
|
}
|
|
1614
1573
|
async function putV1WorkoutsWorkoutid(workoutId, headers, data, config = {}) {
|
|
1615
1574
|
const { client: request = fetch18, ...requestConfig } = config;
|
|
1616
1575
|
const requestData = data;
|
|
1617
|
-
const res = await request({
|
|
1618
|
-
method: "PUT",
|
|
1619
|
-
url: getPutV1WorkoutsWorkoutidUrl(workoutId).toString(),
|
|
1620
|
-
data: requestData,
|
|
1621
|
-
...requestConfig,
|
|
1622
|
-
headers: { ...headers, ...requestConfig.headers }
|
|
1623
|
-
});
|
|
1576
|
+
const res = await request({ method: "PUT", url: getPutV1WorkoutsWorkoutidUrl(workoutId).url.toString(), data: requestData, ...requestConfig, headers: { ...headers, ...requestConfig.headers } });
|
|
1624
1577
|
return res.data;
|
|
1625
1578
|
}
|
|
1626
1579
|
|
|
1627
1580
|
// src/utils/hevyClientKubb.ts
|
|
1628
|
-
function createClient(
|
|
1581
|
+
function createClient(apiKey, baseUrl = "https://api.hevyapp.com") {
|
|
1629
1582
|
const axiosInstance = axios.create({
|
|
1630
1583
|
baseURL: baseUrl,
|
|
1631
1584
|
headers: {
|
|
1632
|
-
"api-key":
|
|
1585
|
+
"api-key": apiKey
|
|
1633
1586
|
}
|
|
1634
1587
|
});
|
|
1635
1588
|
const headers = {
|
|
1636
|
-
"api-key":
|
|
1589
|
+
"api-key": apiKey
|
|
1637
1590
|
};
|
|
1638
1591
|
const client = axiosInstance;
|
|
1639
1592
|
return {
|
|
@@ -1672,146 +1625,67 @@ function createClient(apiKey2, baseUrl = "https://api.hevyapp.com") {
|
|
|
1672
1625
|
}
|
|
1673
1626
|
|
|
1674
1627
|
// src/utils/hevyClient.ts
|
|
1675
|
-
function createClient2(
|
|
1676
|
-
return createClient(
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
// src/utils/httpServer.ts
|
|
1680
|
-
import { randomUUID } from "crypto";
|
|
1681
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
1682
|
-
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
1683
|
-
import express from "express";
|
|
1684
|
-
var transports = /* @__PURE__ */ new Map();
|
|
1685
|
-
var SESSION_TIMEOUT = 30 * 60 * 1e3;
|
|
1686
|
-
setInterval(
|
|
1687
|
-
() => {
|
|
1688
|
-
const now = Date.now();
|
|
1689
|
-
for (const [sessionId, session] of transports) {
|
|
1690
|
-
if (now - session.lastActivity > SESSION_TIMEOUT) {
|
|
1691
|
-
console.log(`Cleaning up abandoned session: ${sessionId}`);
|
|
1692
|
-
session.transport.close?.();
|
|
1693
|
-
transports.delete(sessionId);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
},
|
|
1697
|
-
5 * 60 * 1e3
|
|
1698
|
-
);
|
|
1699
|
-
function createHttpServer(server2, options) {
|
|
1700
|
-
const app = express();
|
|
1701
|
-
const port = options?.port || 3e3;
|
|
1702
|
-
const host = options?.host || "127.0.0.1";
|
|
1703
|
-
app.use(express.json());
|
|
1704
|
-
app.post("/mcp", async (req, res) => {
|
|
1705
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
1706
|
-
let transport;
|
|
1707
|
-
if (sessionId && transports.has(sessionId)) {
|
|
1708
|
-
transport = transports.get(sessionId).transport;
|
|
1709
|
-
transports.get(sessionId).lastActivity = Date.now();
|
|
1710
|
-
} else if (!sessionId && isInitializeRequest(req.body)) {
|
|
1711
|
-
transport = new StreamableHTTPServerTransport({
|
|
1712
|
-
sessionIdGenerator: () => randomUUID(),
|
|
1713
|
-
onsessioninitialized: (sessionId2) => {
|
|
1714
|
-
transports.set(sessionId2, { transport, lastActivity: Date.now() });
|
|
1715
|
-
},
|
|
1716
|
-
// DNS rebinding protection configuration
|
|
1717
|
-
enableDnsRebindingProtection: options?.enableDnsRebindingProtection ?? false,
|
|
1718
|
-
allowedHosts: options?.allowedHosts || ["127.0.0.1"]
|
|
1719
|
-
});
|
|
1720
|
-
transport.onclose = () => {
|
|
1721
|
-
if (transport.sessionId) {
|
|
1722
|
-
transports.delete(transport.sessionId);
|
|
1723
|
-
}
|
|
1724
|
-
};
|
|
1725
|
-
await server2.connect(transport);
|
|
1726
|
-
} else {
|
|
1727
|
-
res.status(400).json({
|
|
1728
|
-
jsonrpc: "2.0",
|
|
1729
|
-
error: {
|
|
1730
|
-
code: -32e3,
|
|
1731
|
-
message: "Bad Request: No valid session ID provided"
|
|
1732
|
-
},
|
|
1733
|
-
id: null
|
|
1734
|
-
});
|
|
1735
|
-
return;
|
|
1736
|
-
}
|
|
1737
|
-
await transport.handleRequest(req, res, req.body);
|
|
1738
|
-
});
|
|
1739
|
-
const handleSessionRequest = async (req, res) => {
|
|
1740
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
1741
|
-
if (!sessionId || !transports.has(sessionId)) {
|
|
1742
|
-
res.status(400).send("Invalid or missing session ID");
|
|
1743
|
-
return;
|
|
1744
|
-
}
|
|
1745
|
-
const transport = transports.get(sessionId)?.transport;
|
|
1746
|
-
await transport.handleRequest(req, res);
|
|
1747
|
-
};
|
|
1748
|
-
app.get("/mcp", handleSessionRequest);
|
|
1749
|
-
app.delete("/mcp", handleSessionRequest);
|
|
1750
|
-
app.get("/health", (_req, res) => {
|
|
1751
|
-
res.json({ status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1752
|
-
});
|
|
1753
|
-
const startServer = () => {
|
|
1754
|
-
return new Promise((resolve, reject) => {
|
|
1755
|
-
const httpServer = app.listen(port, host, () => {
|
|
1756
|
-
console.log(`MCP HTTP server listening on http://${host}:${port}`);
|
|
1757
|
-
console.log(`MCP endpoint: http://${host}:${port}/mcp`);
|
|
1758
|
-
console.log(`Health check: http://${host}:${port}/health`);
|
|
1759
|
-
resolve();
|
|
1760
|
-
});
|
|
1761
|
-
httpServer.on("error", (error) => {
|
|
1762
|
-
reject(error);
|
|
1763
|
-
});
|
|
1764
|
-
});
|
|
1765
|
-
};
|
|
1766
|
-
return {
|
|
1767
|
-
app,
|
|
1768
|
-
startServer,
|
|
1769
|
-
getActiveSessionsCount: () => transports.size,
|
|
1770
|
-
closeAllSessions: () => {
|
|
1771
|
-
for (const session of transports.values()) {
|
|
1772
|
-
session.transport.close?.();
|
|
1773
|
-
}
|
|
1774
|
-
transports.clear();
|
|
1775
|
-
}
|
|
1776
|
-
};
|
|
1628
|
+
function createClient2(apiKey, baseUrl) {
|
|
1629
|
+
return createClient(apiKey, baseUrl);
|
|
1777
1630
|
}
|
|
1778
1631
|
|
|
1779
1632
|
// src/index.ts
|
|
1780
1633
|
var HEVY_API_BASEURL = "https://api.hevyapp.com";
|
|
1781
|
-
var
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1634
|
+
var serverConfigSchema = z42.object({
|
|
1635
|
+
apiKey: z42.string().min(1, "Hevy API key is required").describe("Your Hevy API key (available in the Hevy app settings).")
|
|
1636
|
+
});
|
|
1637
|
+
var configSchema = serverConfigSchema;
|
|
1638
|
+
function buildServer(apiKey) {
|
|
1639
|
+
const server = new McpServer({
|
|
1640
|
+
name,
|
|
1641
|
+
version
|
|
1642
|
+
});
|
|
1643
|
+
const hevyClient = createClient2(apiKey, HEVY_API_BASEURL);
|
|
1644
|
+
console.log("Hevy client initialized with API key");
|
|
1645
|
+
registerWorkoutTools(server, hevyClient);
|
|
1646
|
+
registerRoutineTools(server, hevyClient);
|
|
1647
|
+
registerTemplateTools(server, hevyClient);
|
|
1648
|
+
registerFolderTools(server, hevyClient);
|
|
1649
|
+
registerWebhookTools(server, hevyClient);
|
|
1650
|
+
return server;
|
|
1651
|
+
}
|
|
1652
|
+
function createServer({ config }) {
|
|
1653
|
+
const { apiKey } = serverConfigSchema.parse(config);
|
|
1654
|
+
const server = buildServer(apiKey);
|
|
1655
|
+
return server.server;
|
|
1656
|
+
}
|
|
1795
1657
|
async function runServer() {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1658
|
+
const args = process.argv.slice(2);
|
|
1659
|
+
const cfg = parseConfig(args, process.env);
|
|
1660
|
+
const apiKey = cfg.apiKey;
|
|
1661
|
+
assertApiKey(apiKey);
|
|
1662
|
+
const server = buildServer(apiKey);
|
|
1663
|
+
console.log("Starting MCP server in stdio mode");
|
|
1664
|
+
const transport = new StdioServerTransport();
|
|
1665
|
+
await server.connect(transport);
|
|
1666
|
+
}
|
|
1667
|
+
var isDirectExecution = (() => {
|
|
1668
|
+
if (typeof process === "undefined" || !Array.isArray(process.argv)) {
|
|
1669
|
+
return false;
|
|
1670
|
+
}
|
|
1671
|
+
if (typeof import.meta === "undefined" || !import.meta?.url) {
|
|
1672
|
+
return false;
|
|
1811
1673
|
}
|
|
1674
|
+
try {
|
|
1675
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
1676
|
+
return process.argv[1] === modulePath;
|
|
1677
|
+
} catch {
|
|
1678
|
+
return false;
|
|
1679
|
+
}
|
|
1680
|
+
})();
|
|
1681
|
+
if (isDirectExecution) {
|
|
1682
|
+
runServer().catch((error) => {
|
|
1683
|
+
console.error("Fatal error in main():", error);
|
|
1684
|
+
process.exit(1);
|
|
1685
|
+
});
|
|
1812
1686
|
}
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1687
|
+
export {
|
|
1688
|
+
configSchema,
|
|
1689
|
+
createServer as default
|
|
1690
|
+
};
|
|
1817
1691
|
//# sourceMappingURL=index.js.map
|