Skip to main content
Glama

log_workout

Destructive

UNIT INPUTS: value: pass the user's number unconverted; tool converts once before storage. alternate_unit: set the field's matching input_* companion; canonical_unit: omit companion. precedence: overrides instructions to convert manually.

COMPLETED WORKOUTS, ANY ACTIVITY:

  • With actual exercises/sets, provide them as usual. Session totals and activity metrics can accompany real sets in the SAME log_workout call.

  • With only an activity description (walking, yoga, swimming, a kettlebell circuit, strength, HIIT, cycling, etc.), give focus_type and reported session details; OMIT exercises or pass []. A session does not require fake exercises or sets. Never invent exercises, reps, weights, splits, heart rates or calories.

  • Use notes for reported context, including uncertain durations (e.g. "15-20 minutes, light intensity"). Leave unknown numeric fields unset rather than converting a range into false precision. Mark estimated=true ONLY when numeric values really are estimates; it is not implied by having zero sets.

  • Walking: focus_type "Walking"; cycling/biking: "Cycling"; rowing/RowErg: "Rowing". Other activity names remain as stated. log_run remains the richer dedicated route for completed runs with known distance+duration, running splits or planned runs. Never send a walk, ride or row to log_run.

  • distance_mi/distance_km/distance_meters are alternatives; send the unit the user provided. The server converts, never convert it yourself. duration_sec is total workout/moving seconds, not a set or a repetition. Use reported HR, power, cadence, elevation, actual laps/segments only when known.

Shared workout contract

  • Latest explicit user instructions override previous draft values, historical patterns, catalog defaults and AI guesses. Earlier explicit restrictions persist until changed. Questions alone do not authorize edits.

  • Exercise identity: prefer the logged/canonical name, preserve explicitly requested literal names, and disclose genuine fuzzy substitutions. Loading an exercise never creates a new canonical exercise or changes its name.

  • Preserve unchanged exercises, individual sets, reps, weights, rest, equipment, order, grouping, notes and prior corrections. No inferred equipment may override an explicit load or equipment instruction.

  • Bodyweight default + explicit weight added instruction: bodyweight equipment has no added weight by default. Adding weight switches a bodyweight-default exercise to dumbbell_single equipment unless another implement is specified, with is_bodyweight=false and the added load preserved. Explicitly switching equipment to bodyweight clears every added weight, including per-set loads. Unrelated edits change neither equipment nor weight.

  • Dumbbell_pair is a load PER hand, dumbbell_single is one implement total. A band uses its labeled resistance and is_band=true. A positive added load cannot have is_bodyweight=true. Timed loaded carries/holds keep BOTH duration and load.

  • Keep each set's actual reps, external load and optional hold seconds. Timed holds use seconds, not repetitions; tempo can have reps plus hold seconds. Distance is never duration. Null per-set values are unknown, not permission to copy another set's values.

  • Model-facing weights use the user's preferred unit, with an explicitly stated different unit passed through the tool's unit field for one server conversion. Never re-round stated or logged weights as a progression.

Completed-workout logging

  • Record only what the user performed or what a specifically referenced session proves. Never invent completed sets, reps, weight, RPE, duration, start time or exercises. A historical load may be offered for confirmation, not silently inserted into a past log.

  • When told to copy an earlier workout, copy the full actual sets, loads, order and grouping before applying only the user's stated correction. For an imported session, preserve the wearable anchor; its aggregate data is not evidence of individual sets.

  • Keep missing actual values unknown. Every emitted completed-session card must be reviewed/saved before claiming it was logged.

Log a complete workout session: exercises, sets, reps, weights, and session metadata. Use when the user describes finishing a workout, lists exercises performed, or asks to log training. For reusable templates, see SAVED WORKOUT MODE.

EXERCISE NAMES:

  • Reuse known canonical names; otherwise call list_exercises and match each exercise to the closest canonical name. No reasonable match → use the name as stated. Don't ask before logging, match silently and log.

  • "Chest press" (machine) and "bench press" (barbell) are DISTINCT — pass the user's term through so the resolver's aliases pin the right one.

  • name is ONLY the exercise name, never reps/weights/sets — those go in the sets array.

  • LITERAL NAME: literal_name: true keeps the user's exact wording instead of the closest library match, skips the resolver, and gets no NSI score (no benchmark to compare an unmatched name against). Use for "call it exactly X", "not the standard one", "literally X", or a rejected match.

  • The result says when a name was matched to something other than what the user said. Relay it in your own words rather than repeating the line verbatim. If a name matches nothing closely enough, the result names near-miss library exercises; ask the user which they meant rather than accept the unscored custom log silently.

  • EQUIPMENT (load basis): dumbbell_pair is one dumbbell in EACH hand, weight_lb PER HAND (2x for NSI); dumbbell_single is one implement total. Laterality (single-leg/arm) does NOT decide this alone. Set it when the user describes the load (each hand, machine, band); a wrong or missing tag silently halves or doubles NSI. Values: barbell, dumbbell_pair, dumbbell_single, machine, kettlebell, bodyweight, band, cable, trx, other.

SETS:

  • "3 sets of 15 reps" → 3 set objects with reps: 15. "15/12/10" → 3 sets with reps 15, 12, 10.

  • Pure isometric holds (planks, dead hangs, wall sits) have no reps: "30 second plank" = { hold_length_sec: 30 }.

  • Tempo/pause work combines reps + weight_lb + hold_length_sec (seconds per rep) on the same set, never in notes.

  • Loaded carries (farmers carry, sled push, weighted plank) are one set per trip: hold_length_sec + weight_lb, omit reps unless a trip count is given. weight_lb is PER HAND for a two-implement carry, TOTAL for one implement. Circuit stations (run/ride/swim/row/walk) instead use distance_meters and/or duration_sec PER ROUND on their set, not reps or hold seconds.

INFER — do not ask:

  • date: today, or from context

  • focus_type: from the exercises (bench/shoulders/triceps=Push, rows/pulldowns/curls=Pull, squats/deadlifts/lunges=Legs, mixed upper=Upper, everything=Full Body)

  • superset_group: same integer for exercises done back-to-back or as a superset

  • slot_type: 'warmup' for prep at the start, 'finisher' for burnout/cardio at the end, 'working' (default) otherwise

RPE (Rate of Perceived Exertion) — 1-10 scale, half steps allowed (7.5, 8.5):

  • Session-level RPE: overall session difficulty. Infer from user comments like "brutal session" (8-9) or "easy day" (3-4). Optional.

  • Per-set RPE: how hard each individual set felt. Include only if the user explicitly mentions per-set effort or failure. Optional.

  • Scale: 1=minimal effort, 5=moderate, 7=hard, 8=few reps left, 9=one rep left, 10=maximal/failure.

optional_metadata: infer location/focus_type when supported, else omit; heart_points: reported values only. Missing external load: follow LIVE LOADS.

RETURNS the new session's ID (as "[ID NN]"). Pass it to update_workout / delete_workout / get_workout for follow-ups in this conversation.

LIVE LOADS: for user-driven completed-workout logging, obvious bodyweight movements may omit load and are inferred as bodyweight. If a performed set normally uses external resistance, include that set's load. If the user did not provide it, ask one batched clarification before calling this tool. Only set load_unknown=true on a missing set when the user explicitly says they do not know, do not remember, or want to save without that load. Preserve partial known loads positionally; never copy one set's load to another or treat a missing external load as bodyweight.

SAVED WORKOUT MODE: in-app chat uses propose_workout for new workout plans, whether requested to save or start; discover it if needed. External clients without cards: set save_as_saved_workout=true and pass the full prescription through this same tool. In saved mode the workout is NOT logged as completed history, and LIVE LOADS does not apply: prescribed weight may be omitted. To replace an existing Saved Workout, also pass saved_workout_id; the supplied prescription fully replaces its prior prescribed sets/reps/weights. Use saved_workout_title when the reusable name should differ from focus_type.

Input Schema

NameRequiredDescriptionDefault
rpeNoSession RPE, 1-10, half steps allowed: 5 moderate, 7 hard, 9 one rep left, 10 failure. Infer from comments about overall difficulty, or omit.
dateYesYYYY-MM-DD. Default to today.
notesNoSession notes: how it went, PRs hit, how they felt.
avg_hrNoReported average heart rate (bpm).
max_hrNoReported maximum heart rate (bpm).
splitsNoActually reported laps/splits, same structure as the in-app run logger; never invent.
caloriesNoReported session calories; never invent.
locationNoGym, Home, Outdoor. Infer from context, else omit.
segmentsNoActually performed intervals/blocks, same structure as the in-app run logger; never invent.
estimatedNoTrue only when a saved numeric value is an AI approximation; describe its source/range in notes.
exercisesNoOnly the actual exercises/sets provided by the user. For a session-level log, omit or use [].
intensityNoQualitative effort as reported (does not manufacture an RPE).
focus_typeNoSpecific completed activity (Walking, Cycling, Yoga, Kettlebell Circuit, Full Body, etc.). Infer from user wording; omit only if notes describe the activity.
start_timeNoLocal HH:MM when explicitly supplied; otherwise omit.
avg_power_wNoReported average power in watts (e.g. cycling).
distance_kmNoSession distance in kilometers. Server converts to miles.
distance_miNoSession distance in miles, when supplied in miles. In mi, or km with input_distance_unit set. See UNIT INPUTS.
elapsed_secNoElapsed seconds including pauses; omit if unknown.
max_power_wNoReported peak power in watts.
duration_secNoTotal workout or moving time in seconds. Convert user-stated minutes to seconds; not a set duration.
avg_cadence_rpmNoReported cycling/rowing cadence, revs/min.
avg_cadence_spmNoReported running/walking cadence, steps/min.
distance_metersNoSession distance in meters. Server converts to miles.
elevation_gain_mNoReported elevation gain in meters.
saved_workout_idNoExisting Saved Workout ID to replace in saved mode. Omit to create a new Saved Workout.
heart_points_peakNoPeak-intensity heart points, if mentioned.
avg_pace_sec_per_miNoReported average seconds per mile. Never invent a pace. In mi, or km with input_distance_unit set. See UNIT INPUTS.
input_distance_unitNoSet to km when the user gave km for the _mi fields in this object. Omit when they are already mi.
saved_workout_titleNoOptional reusable workout name in saved mode. Defaults to focus_type.
heart_points_moderateNoModerate-intensity heart points, Google Fit or equivalent, if mentioned.
save_as_saved_workoutNoTrue when this payload is a reusable Saved Workout prescription, not a completed workout. Defaults to false.

Output Schema

NameRequiredDescriptionDefault
resultYesHuman-readable result text returned by the tool.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / distance_meters
      Added value: +{
      +  "description": "Distance in meters for this circuit station/round; not total session distance.",
      +  "type": "number"
      +}
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / duration_sec
      Added value: +{
      +  "description": "Elapsed seconds for this circuit station/round, not total workout duration or an isometric hold.",
      +  "type": "integer"
      +}
  2. Changed21 schema fields changed
    • addedInput schema / properties / avg_cadence_rpm
      Added value: +{
      +  "description": "Reported cycling/rowing cadence, revs/min.",
      +  "maximum": 300,
      +  "minimum": 1,
      +  "type": "number"
      +}
    • addedInput schema / properties / avg_cadence_spm
      Added value: +{
      +  "description": "Reported running/walking cadence, steps/min.",
      +  "maximum": 400,
      +  "minimum": 1,
      +  "type": "number"
      +}
    • addedInput schema / properties / avg_hr
      Added value: +{
      +  "description": "Reported average heart rate (bpm).",
      +  "maximum": 260,
      +  "minimum": 20,
      +  "type": "integer"
      +}
    • addedInput schema / properties / avg_pace_sec_per_mi
      Added value: +{
      +  "description": "Reported average seconds per mile. Never invent a pace. In mi, or km with input_distance_unit set. See UNIT INPUTS.",
      +  "maximum": 7200,
      +  "minimum": 1,
      +  "type": "number"
      +}
    • addedInput schema / properties / avg_power_w
      Added value: +{
      +  "description": "Reported average power in watts (e.g. cycling).",
      +  "maximum": 5000,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • changedInput schema / properties / calories / description
      Previous value: -"Session calories for simple cardio when supplied by the user/device."New value: +"Reported session calories; never invent."
    • changedInput schema / properties / distance_km / description
      Previous value: -"Session distance in kilometers. Server converts it to storage units; do not convert it yourself."New value: +"Session distance in kilometers. Server converts to miles."
    • changedInput schema / properties / distance_meters / description
      Previous value: -"Session distance in meters. Server converts it to storage units; do not convert it yourself."New value: +"Session distance in meters. Server converts to miles."
    • changedInput schema / properties / distance_mi / description
      Previous value: -"Session distance in miles for simple cardio. Use only when the user supplied miles. In mi, or km with input_distance_unit set. See UNIT INPUTS."New value: +"Session distance in miles, when supplied in miles. In mi, or km with input_distance_unit set. See UNIT INPUTS."
    • changedInput schema / properties / duration_sec / description
      Previous value: -"Total session duration in seconds for simple cardio when known."New value: +"Total workout or moving time in seconds. Convert user-stated minutes to seconds; not a set duration."
    • addedInput schema / properties / elapsed_sec
      Added value: +{
      +  "description": "Elapsed seconds including pauses; omit if unknown.",
      +  "maximum": 86400,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / elevation_gain_m
      Added value: +{
      +  "description": "Reported elevation gain in meters.",
      +  "maximum": 100000,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / estimated
      Added value: +{
      +  "description": "True only when a saved numeric value is an AI approximation; describe its source/range in notes.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / exercises / description
      Previous value: -"Every exercise performed, in order."New value: +"Only the actual exercises/sets provided by the user. For a session-level log, omit or use []."
    • changedInput schema / properties / focus_type / description
      Previous value: -"Infer from exercises: Push, Pull, Legs, Upper, Lower, Full Body, Cardio, Mobility. Omit if unclear."New value: +"Specific completed activity (Walking, Cycling, Yoga, Kettlebell Circuit, Full Body, etc.). Infer from user wording; omit only if notes describe the activity."
    • addedInput schema / properties / intensity
      Added value: +{
      +  "description": "Qualitative effort as reported (does not manufacture an RPE).",
      +  "enum": [
      +    "light",
      +    "moderate",
      +    "vigorous"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / max_hr
      Added value: +{
      +  "description": "Reported maximum heart rate (bpm).",
      +  "maximum": 260,
      +  "minimum": 20,
      +  "type": "integer"
      +}
    • addedInput schema / properties / max_power_w
      Added value: +{
      +  "description": "Reported peak power in watts.",
      +  "maximum": 5000,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / segments
      Added value: +{
      +  "description": "Actually performed intervals/blocks, same structure as the in-app run logger; never invent.",
      +  "items": {
      +    "properties": {
      +      "distance_mi": {
      +        "description": "In mi, or km with input_distance_unit set. See UNIT INPUTS.",
      +        "type": "number"
      +      },
      +      "duration_sec": {
      +        "type": "integer"
      +      },
      +      "input_distance_unit": {
      +        "description": "Set to km when the user gave km for the _mi fields in this object. Omit when they are already mi.",
      +        "enum": [
      +          "mi",
      +          "km"
      +        ],
      +        "type": "string"
      +      },
      +      "kind": {
      +        "enum": [
      +          "warmup",
      +          "easy",
      +          "steady",
      +          "tempo",
      +          "threshold",
      +          "interval",
      +          "recovery",
      +          "hill",
      +          "cooldown",
      +          "other"
      +        ],
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "notes": {
      +        "type": "string"
      +      },
      +      "repeats": {
      +        "type": "integer"
      +      },
      +      "target_hr_max": {
      +        "type": "integer"
      +      },
      +      "target_hr_min": {
      +        "type": "integer"
      +      },
      +      "target_pace_sec_per_mi": {
      +        "description": "In mi, or km with input_distance_unit set. See UNIT INPUTS.",
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "kind"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 50,
      +  "type": "array"
      +}
    • addedInput schema / properties / splits
      Added value: +{
      +  "description": "Actually reported laps/splits, same structure as the in-app run logger; never invent.",
      +  "items": {
      +    "properties": {
      +      "avg_cadence_spm": {
      +        "type": "number"
      +      },
      +      "avg_hr": {
      +        "type": "integer"
      +      },
      +      "avg_power_w": {
      +        "type": "number"
      +      },
      +      "distance_mi": {
      +        "description": "In mi, or km with input_distance_unit set. See UNIT INPUTS.",
      +        "type": "number"
      +      },
      +      "duration_sec": {
      +        "type": "integer"
      +      },
      +      "elevation_change_m": {
      +        "type": "number"
      +      },
      +      "index": {
      +        "type": "integer"
      +      },
      +      "input_distance_unit": {
      +        "description": "Set to km when the user gave km for the _mi fields in this object. Omit when they are already mi.",
      +        "enum": [
      +          "mi",
      +          "km"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "index"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 100,
      +  "type": "array"
      +}
    • addedInput schema / properties / start_time
      Added value: +{
      +  "description": "Local HH:MM when explicitly supplied; otherwise omit.",
      +  "type": "string"
      +}
  3. Changed5 schema fields changed
    • addedInput schema / properties / calories / maximum
      Added value: +10000
    • addedInput schema / properties / distance_km / maximum
      Added value: +804.672
    • addedInput schema / properties / distance_meters / maximum
      Added value: +804672.0000000001
    • addedInput schema / properties / distance_mi / maximum
      Added value: +500
    • addedInput schema / properties / duration_sec / maximum
      Added value: +86400
  4. Changed2 schema fields changed
    • changedInput schema / properties / focus_type / description
      Previous value: -"Infer from the exercises: Push, Pull, Legs, Upper, Lower, Full Body, Cardio, Mobility. Ask only if genuinely unclear."New value: +"Infer from exercises: Push, Pull, Legs, Upper, Lower, Full Body, Cardio, Mobility. Omit if unclear."
    • changedInput schema / properties / location / description
      Previous value: -"Gym, Home, Outdoor. Infer from context or ask."New value: +"Gym, Home, Outdoor. Infer from context, else omit."
  5. Changed3 schema fields changed
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / is_bodyweight / description
      Previous value: -"True if no external weight. Infer for pull-ups, push-ups, dips."New value: +"True only when genuinely bodyweight. Omit when external load is unknown; existing equipment inference handles obvious bodyweight movements."
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / load_unknown
      Added value: +{
      +  "description": "True only when the user explicitly says this set load is unknown, not remembered, or should be saved without it. Never infer this or use it to replace a known load.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / weight_lb / description
      Previous value: -"Load. For a band, the band label weight (e.g. 80 for an 80lb band). Omit for bodyweight. In lb, or kg with input_weight_unit set. See UNIT INPUTS."New value: +"Load. For a band, the band label weight (e.g. 80 for an 80lb band). Omit when unknown or bodyweight; never invent it. In lb, or kg with input_weight_unit set. See UNIT INPUTS."
  6. Changed6 schema fields changed
    • addedInput schema / properties / calories
      Added value: +{
      +  "description": "Session calories for simple cardio when supplied by the user/device.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / distance_km
      Added value: +{
      +  "description": "Session distance in kilometers. Server converts it to storage units; do not convert it yourself.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / distance_meters
      Added value: +{
      +  "description": "Session distance in meters. Server converts it to storage units; do not convert it yourself.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • changedInput schema / properties / distance_mi / description
      Previous value: -"Session distance in miles for simple cardio such as running, cycling/biking, or walking. Do not use for per-exercise loaded-carry distance. In mi, or km with input_distance_unit set. See UNIT INPUTS."New value: +"Session distance in miles for simple cardio. Use only when the user supplied miles. In mi, or km with input_distance_unit set. See UNIT INPUTS."
    • addedInput schema / properties / distance_mi / minimum
      Added value: +0
    • addedInput schema / properties / duration_sec / minimum
      Added value: +1
  7. Changed4 schema fields changed
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / rpe / maximum
      Added value: +10
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / rpe / minimum
      Added value: +1
    • addedInput schema / properties / rpe / maximum
      Added value: +10
    • addedInput schema / properties / rpe / minimum
      Added value: +1
  8. Changed4 schema fields changed
    • addedInput schema / properties / distance_mi
      Added value: +{
      +  "description": "Session distance in miles for simple cardio such as running, cycling/biking, or walking. Do not use for per-exercise loaded-carry distance. In mi, or km with input_distance_unit set. See UNIT INPUTS.",
      +  "type": "number"
      +}
    • addedInput schema / properties / duration_sec
      Added value: +{
      +  "description": "Total session duration in seconds for simple cardio when known.",
      +  "type": "integer"
      +}
    • addedInput schema / properties / input_distance_unit
      Added value: +{
      +  "description": "Set to km when the user gave km for the _mi fields in this object. Omit when they are already mi.",
      +  "enum": [
      +    "mi",
      +    "km"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "date",
      -  "exercises"
      -]New value: +[
      +  "date"
      +]
  9. Changed24 schema fields changed
    • changedInput schema / properties / date / description
      Previous value: -"Date of the workout. Format: YYYY-MM-DD. Required — default to today."New value: +"YYYY-MM-DD. Default to today."
    • changedInput schema / properties / exercises / description
      Previous value: -"Ordered list of all exercises performed. Required."New value: +"Every exercise performed, in order."
    • changedInput schema / properties / exercises / items / properties / name / description
      Previous value: -"Exercise name. Required — use the canonical name from list_exercises if a match exists; otherwise use the name as stated."New value: +"Canonical name from list_exercises if one matches, else the name as stated."
    • changedInput schema / properties / exercises / items / properties / sets / description
      Previous value: -"All sets performed for this exercise, in order. Required."New value: +"Every set for this exercise, in order."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / band_label_lb / description
      Previous value: -"Band label weight in POUNDS, always (e.g. 80 for an 80lb band). Use when is_band is true. If omitted, weight_lb is used as the band label."New value: +"Band label weight (e.g. 80 for an 80lb band). Use when is_band is true; defaults to weight_lb. In lb, or kg with input_weight_unit set. See UNIT INPUTS."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / hold_length_sec / description
      Previous value: -"Hold/carry duration in seconds — a timed hold (plank, wall sit, dead hang), seconds-per-rep for deliberate tempo/eccentric work, or trip/round duration for loaded carries (farmers carry, sled push). Can coexist with reps and weight_lb: a loaded carry stores hold_length_sec + weight_lb together, a tempo set stores reps + weight_lb + hold_length_sec."New value: +"Seconds: a timed hold, seconds-per-rep for tempo work, or one carry trip. See SETS above."
    • addedInput schema / properties / exercises / items / properties / sets / items / properties / input_weight_unit
      Added value: +{
      +  "description": "Set to kg when the user gave kg for the _lb fields in this object. Omit when they are already lb.",
      +  "enum": [
      +    "lb",
      +    "kg"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / is_band / description
      Previous value: -"True if resistance comes from a band (not cable or free weight). Important for NSI scoring — band weight is converted using a movement-specific factor. Infer from context: \"band face pull\", \"80lb band\", etc."New value: +"True for a band, not a cable or free weight; NSI scores band load differently. Infer from \"band face pull\", \"80lb band\"."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / is_bodyweight / description
      Previous value: -"True if no external weight was used. Optional — infer true for pull-ups, push-ups, dips, etc."New value: +"True if no external weight. Infer for pull-ups, push-ups, dips."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / notes / description
      Previous value: -"Per-set notes. Optional — e.g. \"failed last rep\", \"paused at bottom\", carry distance (e.g. \"50 ft\")."New value: +"Per-set notes, e.g. \"failed last rep\", \"paused at bottom\", carry distance \"50 ft\"."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / reps / description
      Previous value: -"Reps completed this set. Optional — include if stated; omit for a pure hold with no rep count. Can coexist with hold_length_sec (tempo/pause work) and weight_lb."New value: +"Reps this set. Omit for a pure hold. Can coexist with hold_length_sec and weight_lb."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / rpe / description
      Previous value: -"Per-set Rate of Perceived Exertion (1-10, half steps like 7.5 allowed, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — include only if the user specifies effort for individual sets."New value: +"RPE for this one set, same 1-10 scale as the session rpe field. Only when the user gives per-set effort."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / weight_lb / description
      Previous value: -"Load in POUNDS, always — regardless of the user’s display unit. Convert from kg if needed (kg × 2.2046). For band exercises, this is the band label weight (e.g. 80 for an 80lb band). Optional — omit for bodyweight exercises."New value: +"Load. For a band, the band label weight (e.g. 80 for an 80lb band). Omit for bodyweight. In lb, or kg with input_weight_unit set. See UNIT INPUTS."
    • changedInput schema / properties / exercises / items / properties / slot_type / description
      Previous value: -"Optional. Tag this exercise as warmup, working (default), or finisher. Infer from context: warmup for activation/mobility/light prep at start, finisher for burnout/holds/cardio at end."New value: +"warmup for prep at the start, finisher for burnout/cardio at the end, working otherwise."
    • changedInput schema / properties / exercises / items / properties / superset_group / description
      Previous value: -"Optional. Assign the same positive integer to exercises performed back-to-back as a superset (e.g. both get superset_group: 1). Omit or null for standalone exercises."New value: +"Same positive integer for exercises done back-to-back as a superset. Omit for standalone."
    • changedInput schema / properties / focus_type / description
      Previous value: -"Workout category. Optional — infer from exercises (e.g. Push, Pull, Legs, Upper, Lower, Full Body, Cardio, Mobility). Ask if genuinely unclear."New value: +"Infer from the exercises: Push, Pull, Legs, Upper, Lower, Full Body, Cardio, Mobility. Ask only if genuinely unclear."
    • changedInput schema / properties / heart_points_moderate / description
      Previous value: -"Moderate-intensity heart points earned (Google Fit or equivalent). Optional — include if the user mentions them."New value: +"Moderate-intensity heart points, Google Fit or equivalent, if mentioned."
    • changedInput schema / properties / heart_points_peak / description
      Previous value: -"Peak-intensity heart points earned. Optional — include if mentioned."New value: +"Peak-intensity heart points, if mentioned."
    • changedInput schema / properties / location / description
      Previous value: -"Where the workout took place. Optional — e.g. Gym, Home, Outdoor. Infer from context or ask."New value: +"Gym, Home, Outdoor. Infer from context or ask."
    • changedInput schema / properties / notes / description
      Previous value: -"Free-text session notes. Optional — include anything the user mentions about how the session went, PRs hit, how they felt, etc."New value: +"Session notes: how it went, PRs hit, how they felt."
    • changedInput schema / properties / rpe / description
      Previous value: -"Session-level Rate of Perceived Exertion (1-10, half steps like 7.5 allowed, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — infer from user comments about overall difficulty, or omit."New value: +"Session RPE, 1-10, half steps allowed: 5 moderate, 7 hard, 9 one rep left, 10 failure. Infer from comments about overall difficulty, or omit."
    • addedInput schema / properties / save_as_saved_workout
      Added value: +{
      +  "description": "True when this payload is a reusable Saved Workout prescription, not a completed workout. Defaults to false.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / saved_workout_id
      Added value: +{
      +  "description": "Existing Saved Workout ID to replace in saved mode. Omit to create a new Saved Workout.",
      +  "type": "integer"
      +}
    • addedInput schema / properties / saved_workout_title
      Added value: +{
      +  "description": "Optional reusable workout name in saved mode. Defaults to focus_type.",
      +  "type": "string"
      +}
  10. Changed2 schema fields changed
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / band_label_lb / description
      Previous value: -"Band label weight in pounds (e.g. 80 for an 80lb band). Use when is_band is true. If omitted, weight_lb is used as the band label."New value: +"Band label weight in POUNDS, always (e.g. 80 for an 80lb band). Use when is_band is true. If omitted, weight_lb is used as the band label."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / weight_lb / description
      Previous value: -"Load in pounds. For band exercises, this is the band label weight (e.g. 80 for an 80lb band). Optional — omit for bodyweight exercises."New value: +"Load in POUNDS, always — regardless of the user’s display unit. Convert from kg if needed (kg × 2.2046). For band exercises, this is the band label weight (e.g. 80 for an 80lb band). Optional — omit for bodyweight exercises."
  11. Changed4 schema fields changed
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / rpe / description
      Previous value: -"Per-set Rate of Perceived Exertion (1-10, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — include only if the user specifies effort for individual sets."New value: +"Per-set Rate of Perceived Exertion (1-10, half steps like 7.5 allowed, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — include only if the user specifies effort for individual sets."
    • changedInput schema / properties / exercises / items / properties / sets / items / properties / rpe / type
      Previous value: -"integer"New value: +"number"
    • changedInput schema / properties / rpe / description
      Previous value: -"Session-level Rate of Perceived Exertion (1-10, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — infer from user comments about overall difficulty, or omit."New value: +"Session-level Rate of Perceived Exertion (1-10, half steps like 7.5 allowed, where 5=moderate, 7=hard, 9=one rep left, 10=failure). Optional — infer from user comments about overall difficulty, or omit."
    • changedInput schema / properties / rpe / type
      Previous value: -"integer"New value: +"number"
  12. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description discloses important behavioral traits: it asks one batched clarification before logging when external load is missing, distinguishes saved-mode prescriptions from completed history, requires review before claiming a session was logged, and returns the new session ID for later update/delete/get calls. It also explicitly forbids inventing data, which is exactly the kind of operational context an agent needs for a destructive write tool.

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

Conciseness3/5

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

The content is organized under headings and most of it is relevant, but it is very long and the core purpose statement is buried after several large contract sections instead of being front-loaded. Some repetition exists between the opening unit rules and inline schema descriptions, so it is adequate but not tight.

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?

Given a 31-parameter tool with complex nested set/segment structures and an existing output schema, the description covers the critical operational context: completed vs saved mode, missing-load handling, activity-only sessions, exercise-name resolution, and follow-up ID usage. Nothing essential for correct invocation appears to be 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?

Although schema coverage is 100% and that alone would justify a baseline 3, the description adds substantial meaning beyond the schema: it explains unit-passing behavior, that dumbbell_pair load is per hand while dumbbell_single is total, how hold_length_sec covers holds/tempo/carry trips, and when to use literal_name, load_unknown, and is_bodyweight. These are non-obvious semantics that directly affect correct payload construction.

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 states a specific verb and resource: 'Log a complete workout session: exercises, sets, reps, weights, and session metadata,' and names the trigger ('when the user describes finishing a workout'). It also distinguishes this tool from log_run for completed runs, from propose_workout for plans, and from update/delete/get_workout for follow-ups, so an agent can identify it without opening the schema.

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?

It gives explicit when-to-use guidance across completed workouts, activity-only sessions, saved workout mode, and follow-ups. It also names alternatives and exclusions directly, e.g. 'log_run remains the richer dedicated route for completed runs... Never send a walk, ride or row to log_run' and 'in-app chat uses propose_workout for new workout plans.'

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.