Skip to main content
Glama

create-routine

Design and save a personalized workout routine in Hevy by specifying title, exercises, sets, and optional folder assignment. Returns the complete routine details with a unique ID for tracking.

Instructions

Create a new workout routine in your Hevy account. Requires title and at least one exercise with sets. Optionally assign to a specific folder. Returns the complete routine details upon successful creation including the newly assigned routine ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
exercisesYes
folderIdNo
notesNo
titleYes

Implementation Reference

  • The execution logic for the 'create-routine' tool. Handles input parameters, maps them to the Hevy API request format, calls the API to create the routine, formats the response, and returns it as JSON.
    withErrorHandling(async (args) => {
    	if (!hevyClient) {
    		throw new Error(
    			"API client not initialized. Please provide HEVY_API_KEY.",
    		);
    	}
    	const { title, folderId, notes, exercises } = args as CreateRoutineParams;
    	const data = await hevyClient.createRoutine({
    		routine: {
    			title,
    			folder_id: folderId ?? null,
    			notes: notes ?? "",
    			exercises: exercises.map(
    				(exercise): PostRoutinesRequestExercise => ({
    					exercise_template_id: exercise.exerciseTemplateId,
    					superset_id: exercise.supersetId ?? null,
    					rest_seconds: exercise.restSeconds ?? null,
    					notes: exercise.notes ?? null,
    					sets: exercise.sets.map(
    						(set): PostRoutinesRequestSet => ({
    							type: set.type as PostRoutinesRequestSetTypeEnumKey,
    							weight_kg: set.weightKg ?? null,
    							reps: set.reps ?? null,
    							distance_meters: set.distanceMeters ?? null,
    							duration_seconds: set.durationSeconds ?? null,
    							custom_metric: set.customMetric ?? null,
    						}),
    					),
    				}),
    			),
    		},
    	});
    
    	if (!data) {
    		return createEmptyResponse(
    			"Failed to create routine: Server returned no data",
    		);
    	}
    
    	const routine = formatRoutine(data);
    	return createJsonResponse(routine, {
    		pretty: true,
    		indent: 2,
    	});
    }, "create-routine"),
  • Zod input schema defining the parameters for the 'create-routine' tool: title, optional folderId, notes, and array of exercises with sets.
    {
    	title: z.string().min(1),
    	folderId: z.coerce.number().nullable().optional(),
    	notes: z.string().optional(),
    	exercises: z.array(
    		z.object({
    			exerciseTemplateId: z.string().min(1),
    			supersetId: z.coerce.number().nullable().optional(),
    			restSeconds: z.coerce.number().int().min(0).optional(),
    			notes: z.string().optional(),
    			sets: z.array(
    				z.object({
    					type: z
    						.enum(["warmup", "normal", "failure", "dropset"])
    						.default("normal"),
    					weightKg: z.coerce.number().optional(),
    					reps: z.coerce.number().int().optional(),
    					distanceMeters: z.coerce.number().int().optional(),
    					durationSeconds: z.coerce.number().int().optional(),
    					customMetric: z.coerce.number().optional(),
    				}),
    			),
    		}),
    	),
    },
  • The server.tool() call that registers the 'create-routine' tool with the MCP server, providing name, description, input schema, and handler function.
    server.tool(
    	"create-routine",
    	"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.",
    	{
    		title: z.string().min(1),
    		folderId: z.coerce.number().nullable().optional(),
    		notes: z.string().optional(),
    		exercises: z.array(
    			z.object({
    				exerciseTemplateId: z.string().min(1),
    				supersetId: z.coerce.number().nullable().optional(),
    				restSeconds: z.coerce.number().int().min(0).optional(),
    				notes: z.string().optional(),
    				sets: z.array(
    					z.object({
    						type: z
    							.enum(["warmup", "normal", "failure", "dropset"])
    							.default("normal"),
    						weightKg: z.coerce.number().optional(),
    						reps: z.coerce.number().int().optional(),
    						distanceMeters: z.coerce.number().int().optional(),
    						durationSeconds: z.coerce.number().int().optional(),
    						customMetric: z.coerce.number().optional(),
    					}),
    				),
    			}),
    		),
    	},
    	withErrorHandling(async (args) => {
    		if (!hevyClient) {
    			throw new Error(
    				"API client not initialized. Please provide HEVY_API_KEY.",
    			);
    		}
    		const { title, folderId, notes, exercises } = args as CreateRoutineParams;
    		const data = await hevyClient.createRoutine({
    			routine: {
    				title,
    				folder_id: folderId ?? null,
    				notes: notes ?? "",
    				exercises: exercises.map(
    					(exercise): PostRoutinesRequestExercise => ({
    						exercise_template_id: exercise.exerciseTemplateId,
    						superset_id: exercise.supersetId ?? null,
    						rest_seconds: exercise.restSeconds ?? null,
    						notes: exercise.notes ?? null,
    						sets: exercise.sets.map(
    							(set): PostRoutinesRequestSet => ({
    								type: set.type as PostRoutinesRequestSetTypeEnumKey,
    								weight_kg: set.weightKg ?? null,
    								reps: set.reps ?? null,
    								distance_meters: set.distanceMeters ?? null,
    								duration_seconds: set.durationSeconds ?? null,
    								custom_metric: set.customMetric ?? null,
    							}),
    						),
    					}),
    				),
    			},
    		});
    
    		if (!data) {
    			return createEmptyResponse(
    				"Failed to create routine: Server returned no data",
    			);
    		}
    
    		const routine = formatRoutine(data);
    		return createJsonResponse(routine, {
    			pretty: true,
    			indent: 2,
    		});
    	}, "create-routine"),
  • TypeScript type definition for CreateRoutineParams used in the handler to type-check the input arguments.
    type CreateRoutineParams = {
    	title: string;
    	folderId?: number | null;
    	notes?: string;
    	exercises: Array<{
    		exerciseTemplateId: string;
    		supersetId?: number | null;
    		restSeconds?: number;
    		notes?: string;
    		sets: Array<{
    			type: "warmup" | "normal" | "failure" | "dropset";
    			weightKg?: number;
    			reps?: number;
    			distanceMeters?: number;
    			durationSeconds?: number;
    			customMetric?: number;
    		}>;
    	}>;
    };

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