Skip to main content
Glama

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
NameRequiredDescriptionDefault
descriptionNo
endTimeYes
exercisesYes
isPrivateNo
startTimeYes
titleYes

Implementation Reference

  • 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", ), );
  • 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(), }), ), }), ), },
  • 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);

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