create-workout
Add a new workout to your Hevy account by specifying title, start/end times, and exercises with sets. Returns complete workout details, including a unique ID for tracking.
Instructions
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.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | No | ||
| endTime | Yes | ||
| exercises | Yes | ||
| isPrivate | No | ||
| startTime | Yes | ||
| title | Yes |
Implementation Reference
- src/tools/workouts.ts:188-242 (handler)Handler function for the 'create-workout' tool. Builds the request body from inputs, calls hevyClient.createWorkout API, formats the response using formatWorkout, and returns JSON response.withErrorHandling( async ({ title, description, startTime, endTime, isPrivate, exercises, }) => { if (!hevyClient) { throw new Error( "API client not initialized. Please provide HEVY_API_KEY.", ); } const requestBody: PostWorkoutsRequestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, rpe: set.rpe || null, customMetric: set.customMetric || null, })), })), }, }; const data = await hevyClient.createWorkout(requestBody); if (!data) { return createEmptyResponse( "Failed to create workout: Server returned no data", ); } const workout = formatWorkout(data); return createJsonResponse(workout, { pretty: true, indent: 2, }); }, "create-workout", ), );
- src/tools/workouts.ts:161-187 (schema)Input schema for 'create-workout' tool using Zod, validating title, times, privacy, and complex exercises structure with sets.{ title: z.string().min(1), description: z.string().optional().nullable(), startTime: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), endTime: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), isPrivate: z.boolean().default(false), exercises: z.array( z.object({ exerciseTemplateId: z.string().min(1), supersetId: z.coerce.number().nullable().optional(), notes: z.string().optional().nullable(), sets: z.array( z.object({ type: z .enum(["warmup", "normal", "failure", "dropset"]) .default("normal"), weightKg: z.coerce.number().optional().nullable(), reps: z.coerce.number().int().optional().nullable(), distanceMeters: z.coerce.number().int().optional().nullable(), durationSeconds: z.coerce.number().int().optional().nullable(), rpe: z.coerce.number().optional().nullable(), customMetric: z.coerce.number().optional().nullable(), }), ), }), ), },
- src/tools/workouts.ts:159-242 (registration)Direct registration of the 'create-workout' tool on the MCP server within registerWorkoutTools function."create-workout", "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.", { title: z.string().min(1), description: z.string().optional().nullable(), startTime: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), endTime: z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), isPrivate: z.boolean().default(false), exercises: z.array( z.object({ exerciseTemplateId: z.string().min(1), supersetId: z.coerce.number().nullable().optional(), notes: z.string().optional().nullable(), sets: z.array( z.object({ type: z .enum(["warmup", "normal", "failure", "dropset"]) .default("normal"), weightKg: z.coerce.number().optional().nullable(), reps: z.coerce.number().int().optional().nullable(), distanceMeters: z.coerce.number().int().optional().nullable(), durationSeconds: z.coerce.number().int().optional().nullable(), rpe: z.coerce.number().optional().nullable(), customMetric: z.coerce.number().optional().nullable(), }), ), }), ), }, withErrorHandling( async ({ title, description, startTime, endTime, isPrivate, exercises, }) => { if (!hevyClient) { throw new Error( "API client not initialized. Please provide HEVY_API_KEY.", ); } const requestBody: PostWorkoutsRequestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, rpe: set.rpe || null, customMetric: set.customMetric || null, })), })), }, }; const data = await hevyClient.createWorkout(requestBody); if (!data) { return createEmptyResponse( "Failed to create workout: Server returned no data", ); } const workout = formatWorkout(data); return createJsonResponse(workout, { pretty: true, indent: 2, }); }, "create-workout", ), );
- src/index.ts:40-40 (registration)Top-level call to registerWorkoutTools in the main server setup, which registers 'create-workout' among other workout tools.registerWorkoutTools(server, hevyClient);