Skip to main content
Glama

Povver — Strength Training

Update Workout

update_workout
Idempotent

Correct a workout that is already recorded - fix a weight, add a note, adjust reps. Supply only the fields to change: anything omitted is left exactly as it is.

Call get_workout first to see the current state. Do NOT build an exercises array from list_workouts - that returns set COUNTS, not sets, and a replacement assembled from it would write zeroes over what the athlete logged. A replacement that would drop most of the logged sets is rejected outright.

To change the exercise list, pass the COMPLETE exercises array - it replaces the existing list wholesale, so omitting an exercise removes it. Omit the exercises field entirely to leave every exercise untouched. Two things survive a replacement you do not mention: leave the sets field off an exercise and its existing sets are kept (so you can rename or reorder without resending set data), and leave the notes field off and the athlete's own note is kept - pass null to clear it. Echo each existing set's id from get_workout: a set sent with its id keeps every stored field you leave out, and a set without one is treated as new.

Idempotent on workout_id: repeating the same call is safe. To remove a workout instead, use delete_workout.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoNew session name.
notesNoNew session notes.
end_timeNoCorrected end time (ISO 8601).
exercisesNoCOMPLETE replacement exercise list. Omit to leave the existing exercises untouched.
start_timeNoCorrected start time (ISO 8601).
workout_idYesID of the workout to update (from list_workouts or get_workout).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changed
    • addedInput schema / properties / exercises / items / properties / exercise_id / description
      Added value: +"Catalog exercise ID. Omit only when sending new_exercise."
    • addedInput schema / properties / exercises / items / properties / measure
      Added value: +{
      +  "description": "How this exercise is counted: \"reps\" (default), \"duration\" (a hold or timed effort: give duration_s on each set, no reps or rir) or \"distance\" (a carry or run: give distance_m). Omit to keep the stored measure, or the exercise's default for a new one. weight, distance_m and duration_s are ALWAYS kg, metres and seconds.",
      +  "enum": [
      +    "reps",
      +    "duration",
      +    "distance"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / exercises / items / properties / new_exercise
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "ONLY for a lift that does not exist yet (search_exercises first; a name that already exists is rejected with its candidates). Send this INSTEAD of exercise_id. The exercise is created for the user, who can edit or delete it in the app. Simple form only: name (2-80 chars), load_kind (\"external\" weighted, \"bodyweight\", \"none\"), measures (reps, duration, distance), groups (1-3 of chest, back, shoulders, quads, hamstrings, glutes, biceps, triceps, calves, abs; cardio may omit), optional equipment, activity (\"strength\" default or \"cardio\"), and for bodyweight bodyweight_fraction 0.95 (most of bodyweight moves), 0.64 (partly) or null (unknown).",
      +  "properties": {
      +    "activity": {
      +      "enum": [
      +        "strength",
      +        "cardio"
      +      ],
      +      "type": "string"
      +    },
      +    "bodyweight_fraction": {
      +      "anyOf": [
      +        {
      +          "const": 0.95,
      +          "type": "number"
      +        },
      +        {
      +          "const": 0.64,
      +          "type": "number"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "equipment": {
      +      "items": {
      +        "maxLength": 40,
      +        "type": "string"
      +      },
      +      "maxItems": 3,
      +      "type": "array"
      +    },
      +    "groups": {
      +      "items": {
      +        "maxLength": 40,
      +        "type": "string"
      +      },
      +      "maxItems": 3,
      +      "minItems": 1,
      +      "type": "array"
      +    },
      +    "load_kind": {
      +      "enum": [
      +        "external",
      +        "bodyweight",
      +        "none"
      +      ],
      +      "type": "string"
      +    },
      +    "measures": {
      +      "items": {
      +        "enum": [
      +          "reps",
      +          "duration",
      +          "distance"
      +        ],
      +        "type": "string"
      +      },
      +      "maxItems": 3,
      +      "minItems": 1,
      +      "type": "array"
      +    },
      +    "name": {
      +      "maxLength": 400,
      +      "type": "string"
      +    },
      +    "unilateral": {
      +      "const": false,
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "name",
      +    "load_kind",
      +    "measures"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / assist_band
      Added value: +{
      +  "description": "True when the assistance is a band. Omit to keep the stored value; null clears it.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / assist_kg
      Added value: +{
      +  "anyOf": [
      +    {
      +      "exclusiveMinimum": 0,
      +      "maximum": 1500,
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Kilograms of assistance on an assisted bodyweight lift (> 0, max 1500). Never a negative weight: \"assist 25 kg\" is assist_kg 25. Do not combine with a weight above 0. Omit to keep the stored value; null clears it."
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / rpe
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 10,
      +      "minimum": 1,
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "RPE, half steps fine. Omit to keep the stored value (the set must carry its id); null clears it."
      +}
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / weight_kg / anyOf
      Previous value: -[
      -  {
      -    "maximum": 1500,
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "maximum": 1500,
      +    "minimum": 0,
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / weight_kg / description
      Added value: +"Load in kilograms, never negative: assistance is assist_kg."
    • removedInput schema / properties / exercises / items / required
      Removed value: -[
      -  "exercise_id"
      -]
  2. Changed4 schema fields changed
    • addedInput schema / properties / exercises / items / properties / position / description
      Added value: +"Order within the session (0-based integer)."
    • addedInput schema / properties / exercises / items / properties / position / maximum
      Added value: +9007199254740991
    • addedInput schema / properties / exercises / items / properties / position / minimum
      Added value: +0
    • changedInput schema / properties / exercises / items / properties / position / type
      Previous value: -"number"New value: +"integer"
  3. Changed17 schema fields changed
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m / anyOf
      Added value: +[
      +  {
      +    "maximum": 100000,
      +    "minimum": 0,
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m / description
      Previous value: -"Echo the value get_workout returned (distance work, metres); omitting it erases it."New value: +"Distance work, metres. Omit to keep the stored value (the set must carry its id); null clears it."
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m / maximum
      Removed value: -100000
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m / minimum
      Removed value: -0
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m / type
      Removed value: -"number"
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s / anyOf
      Added value: +[
      +  {
      +    "maximum": 86400,
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s / description
      Previous value: -"Echo the value get_workout returned (timed work, seconds); omitting it erases it."New value: +"Timed work, seconds. Omit to keep the stored value (the set must carry its id); null clears it."
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s / maximum
      Removed value: -86400
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s / minimum
      Removed value: -0
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s / type
      Removed value: -"integer"
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 200,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The set's id from get_workout. ALWAYS echo it on a set that already exists: a set sent with its id keeps every stored field you leave out (timing, the failure flag, the load basis, where it was imported from). A set without an id (or with id null, as some older sets show) is a NEW set."
      +}
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / is_failure / description
      Previous value: -"Echo the value get_workout returned; omitting it on a set that had it erases it."New value: +"Omit to keep the stored value (the set must carry its id); false or null clears it."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / is_failure / type
      Previous value: -"boolean"New value: +[
      +  "boolean",
      +  "null"
      +]
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / load_basis / anyOf
      Added value: +[
      +  {
      +    "enum": [
      +      "per_implement",
      +      "total"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / load_basis / description
      Previous value: -"Echo the value get_workout returned for this set (\"per_implement\" | \"total\"); omitting it on a set that had one erases it."New value: +"\"per_implement\" | \"total\". Omit to keep the stored value (the set must carry its id); null clears it."
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / load_basis / enum
      Removed value: -[
      -  "per_implement",
      -  "total"
      -]
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / load_basis / type
      Removed value: -"string"
  4. Changed9 schema fields changed
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / distance_m
      Added value: +{
      +  "description": "Echo the value get_workout returned (distance work, metres); omitting it erases it.",
      +  "maximum": 100000,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / duration_s
      Added value: +{
      +  "description": "Echo the value get_workout returned (timed work, seconds); omitting it erases it.",
      +  "maximum": 86400,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / is_failure
      Added value: +{
      +  "description": "Echo the value get_workout returned; omitting it on a set that had it erases it.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / reps / maximum
      Added value: +200
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / reps / minimum
      Added value: +0
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / reps / type
      Previous value: -"number"New value: +"integer"
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / rir / anyOf
      Added value: +[
      +  {
      +    "maximum": 10,
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / rir / description
      Added value: +"Reps in reserve as an INTEGER, or null."
    • removedInput schema / properties / exercises / items / properties / sets / items / properties / rir / type
      Removed value: -[
      -  "number",
      -  "null"
      -]
  5. Changed1 schema field changed
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / load_basis
      Added value: +{
      +  "description": "Echo the value get_workout returned for this set (\"per_implement\" | \"total\"); omitting it on a set that had one erases it.",
      +  "enum": [
      +    "per_implement",
      +    "total"
      +  ],
      +  "type": "string"
      +}
  6. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare idempotency, non-destructiveness and openWorld=false; the description corroborates idempotency and goes well beyond by disclosing the guard rail that a replacement dropping most logged sets is rejected, the wholesale-replacement behavior of the exercises array, and the omit-keeps / null-clears preservation rules. This is rich behavioral context the structured fields do not convey.

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

Conciseness4/5

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

Long, but front-loaded with purpose and patch semantics and every sentence carries a distinct rule (get_workout first, list_workouts trap, replacement behavior, id echo, idempotency, delete alternative). Slightly verbose and could be tightened, but there is no filler.

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

Completeness5/5

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

For a complex mutation tool with no output schema, the description covers the full call contract: prerequisite read step, replacement vs omission semantics, set identity handling, rejection conditions, idempotency, and the removal alternative. Nothing an agent needs to invoke this correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the per-field omit/null semantics are already documented. The description nonetheless adds the holistic model an agent needs: exercises replaces wholesale, set ids must be echoed from get_workout, and sets without ids are treated as new — synthesizing rules that span multiple parameters rather than restating the schema.

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?

States a specific verb and resource ('Correct a workout that is already recorded') and immediately disambiguates with concrete examples (fix a weight, add a note, adjust reps). The patch semantics ('supply only the fields to change') and the explicit sibling routing ('use delete_workout instead') make it unmistakable versus create_workout/delete_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 prescribes the workflow ('Call get_workout first'), names an exclusion ('Do NOT build an exercises array from list_workouts'), and points to the alternative for removal ('use delete_workout'). It even explains why the exclusion exists (list_workouts returns counts, not sets), which is exactly the kind of guidance an agent needs.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.