Skip to main content
Glama

update-workout

Modify workout details such as title, description, start/end times, privacy settings, and exercise data. Provides the updated workout with all changes applied for accurate tracking.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
descriptionNo
endTimeYes
exercisesYes
isPrivateNo
startTimeYes
titleYes
workoutIdYes

Implementation Reference

  • The core handler function for the 'update-workout' tool. It maps input parameters to the Hevy API request format, calls the updateWorkout method on the Hevy client, handles errors, formats the response using formatWorkout, and returns JSON.
    async ({ workoutId, title, description, startTime, endTime, isPrivate, exercises, }) => { const requestBody: PostWorkoutsRequestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise: ExerciseInput) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set: ExerciseSetInput) => ({ 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.updateWorkout(workoutId, requestBody); if (!data) { return createEmptyResponse( `Failed to update workout with ID ${workoutId}`, ); } const workout = formatWorkout(data); return createJsonResponse(workout, { pretty: true, indent: 2, });
  • Zod schema defining the input parameters for the 'update-workout' tool, including workoutId, title, optional description, required ISO timestamps, privacy flag, and array of exercises with detailed set data.
    { workoutId: z.string().min(1), 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(), }), ), }), ), },
  • Registers the 'update-workout' tool with the MCP server using server.tool(), providing name, description, input schema, and error-handling wrapped handler.
    "update-workout", "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.", { workoutId: z.string().min(1), 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 ({ workoutId, title, description, startTime, endTime, isPrivate, exercises, }) => { const requestBody: PostWorkoutsRequestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise: ExerciseInput) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set: ExerciseSetInput) => ({ 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.updateWorkout(workoutId, requestBody); if (!data) { return createEmptyResponse( `Failed to update workout with ID ${workoutId}`, ); } const workout = formatWorkout(data); return createJsonResponse(workout, { pretty: true, indent: 2, }); }, "update-workout-operation", ), );
  • src/index.ts:40-40 (registration)
    Top-level call to register all workout tools, including 'update-workout', on the main MCP server instance.
    registerWorkoutTools(server, hevyClient);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrisdoc/hevy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server