Skip to main content
Glama

create_workout

Log a completed workout to Hevy with exercises, sets, notes, and timing.

Instructions

Log a completed workout to Hevy.

workout shape: { title, description?, start_time, end_time, is_private?, exercises: [ { exercise_template_id, notes?, superset_id?, sets: [ { type, weight_kg?, reps?, rpe?, distance_meters?, duration_seconds? } ] } ] }

Resolve exercise_template_id values via search_exercise_templates before calling this tool — never invent IDs.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
workoutYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler for the 'create_workout' tool. Validates the input workout dict using the Workout Pydantic model, posts it to the Hevy API via POST /workouts, and returns a confirmation message with the API response data.
    @mcp.tool()
    @tool_guard
    async def create_workout(workout: dict[str, Any]) -> dict[str, Any]:
        """Log a completed workout to Hevy.
    
        `workout` shape:
          { title, description?, start_time, end_time, is_private?, exercises: [
              { exercise_template_id, notes?, superset_id?, sets: [
                  { type, weight_kg?, reps?, rpe?, distance_meters?, duration_seconds? }
              ] }
          ] }
    
        Resolve `exercise_template_id` values via `search_exercise_templates` *before*
        calling this tool — never invent IDs.
        """
        validated = Workout.model_validate(workout).model_dump(exclude_none=True)
        data = await client.post("/workouts", json={"workout": validated})
        return {"text": "Workout logged.", "data": data}
  • Pydantic schema/model for the Workout resource, used to validate and deserialize the input to create_workout. Models fields like title, description, start_time, end_time, is_private, and exercises (list of WorkoutExercise).
    class Workout(_Base):
        id: str | None = None
        title: str
        description: str | None = None
        start_time: datetime | None = None
        end_time: datetime | None = None
        is_private: bool = False
        exercises: list[WorkoutExercise] = Field(default_factory=list)
  • Pydantic schema for a workout exercise, referenced in create_workout input. Contains exercise_template_id, superset_id, notes, and a list of WorkoutSet.
    class WorkoutExercise(_Base):
        exercise_template_id: str
        superset_id: int | None = None
        notes: str | None = None
        sets: list[WorkoutSet] = Field(default_factory=list)
  • Pydantic schema for an individual set within a workout exercise, used in the create_workout input validation chain.
    class WorkoutSet(_Base):
        index: int | None = None
        type: SetType = "normal"
        weight_kg: float | None = None
        reps: int | None = None
        distance_meters: float | None = None
        duration_seconds: int | None = None
        rpe: float | None = None
        custom_metric: float | None = None
  • Registration via the @mcp.tool() decorator inside the register() function. The create_workout tool is registered as an MCP tool on the mcp server instance when register() is called.
    def register(mcp, ctx) -> None:
        client = ctx.client
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must cover behavioral traits. It explains the input structure but does not mention success responses, error conditions, or side effects beyond creation. Some behavioral context is missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is succinct: a one-line purpose, a code block for the parameter shape, and a clear prerequisite statement. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description sufficiently covers the complex parameter and prerequisite, but lacks details on return values or error handling. Since an output schema exists, the omission is acceptable, but some behavioral context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only defines 'workout' as an object with additionalProperties true, offering no structure. The description compensates fully by detailing the exact shape with nested fields, optional markers, and required subfields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Log a completed workout to Hevy', specifying the verb (log), resource (workout), and context (completed). This distinguishes it from sibling tools like create_routine or update_workout.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to resolve exercise_template_ids via search_exercise_templates before calling and warns never to invent IDs. This provides clear guidance on prerequisite actions and correct usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Vellarasan/hevy-mcp'

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