> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chrisdoc.dev/hevy-mcp/llms.txt
> Use this file to discover all available pages before exploring further.

# Workout tools — read, create, and update Hevy workouts

> Reference for all 7 Hevy MCP workout tools: get-training-summary, get-workouts, get-workout, get-workout-count, get-workout-events, create-workout, and update-workout.

Hevy MCP provides **7 workout tools** covering every aspect of your training data: high-level analysis with a single call, browsing and searching your full workout history, logging completed sessions, and tracking incremental changes to your account. Five tools are read-only; two are mutation tools that write back to Hevy.

***

## get-training-summary

Summarizes recent workout activity and body-measurement trends in a single tool call, returning compact session evidence without requiring separate count queries or manual pagination.

**Kind:** Read-only

### Input parameters

<ParamField query="weeks" type="integer" default="4">
  Number of recent weeks to include in the summary. Must be between **1** and **12** (inclusive). Defaults to `4`.
</ParamField>

### What it returns

The response contains three top-level sections:

* **`period`** — `startDate`, `endDate`, and `weeks` describing the exact window analyzed.
* **`workouts`** — aggregate counts (`count`, `totalDurationSeconds`, `exerciseCount`, `setCount`), a `uniqueExerciseTemplateIds` array, and a `sessions` list. Each session entry includes the workout `id`, `title`, `startTime`, `endTime`, `durationSeconds`, `exerciseCount`, and `setCount`.
* **`bodyMeasurements`** — `count` of entries in the window, the `earliest` and `latest` measurement snapshots (each with `date`, `weightKg`, `leanMassKg`, `fatPercent`), and a `weightChangeKg` delta.

A `workflow` metadata block reports the number of API pages scanned and the cache status.

### Example usage

> "Give me a training summary for the last six weeks."

Ask the assistant for a progress review and it will call `get-training-summary` with `weeks: 6`, returning everything needed to analyze frequency, volume, and body-composition trends in one round trip.

### Notes

* The summary covers the **most recent** N weeks relative to the current UTC date; there is no way to target a historical window.
* The tool internally paginates through workouts and body measurements to collect all records in the window — you do not need to page manually.
* Use this tool instead of calling `get-workout-count` + `get-workouts` when you want a bounded progress overview.

***

## get-workouts

Lists workouts from newest to oldest with exercise and timing details.

**Kind:** Read-only

### Input parameters

<ParamField query="page" type="number" default="1">
  Page number to retrieve. Must be **≥ 1**. Defaults to `1`.
</ParamField>

<ParamField query="pageSize" type="integer" default="5">
  Number of workouts per page. Must be between **1** and **10** (inclusive). Defaults to `5`.
</ParamField>

### Example usage

> "Show me my three most recent workouts."

The assistant calls `get-workouts` with `page: 1, pageSize: 3` and presents each workout's title, start time, exercises, and sets.

### Notes

* Results are always ordered newest first.
* `pageSize` is hard-capped at **10**. To retrieve more workouts, increment `page`.
* Use `get-workout-count` first if you need to know how many total pages exist.
* When you already have a workout ID, prefer `get-workout` to avoid fetching an entire page.

***

## get-workout

Retrieves complete details for a single workout by its ID.

**Kind:** Read-only

### Input parameters

<ParamField query="workoutId" type="string" required>
  The ID of the workout to retrieve. Must be a non-empty string. Obtain this value from a `get-workouts` listing, a `get-workout-events` entry, or the response from `create-workout`.
</ParamField>

### Example usage

> "Show me everything about my last chest day."

After `get-workouts` identifies the workout ID, the assistant calls `get-workout` with that ID to fetch the full set-by-set breakdown.

### Notes

* `workoutId` must come from an existing Hevy workout. There is no search-by-title equivalent; use `get-workouts` to browse and identify IDs first.
* Do not use this tool to list multiple workouts — each call retrieves exactly one record.

***

## get-workout-count

Returns the total number of workouts logged in the account as a single integer.

**Kind:** Read-only

### Input parameters

This tool takes no input parameters.

### Example usage

> "How many workouts have I logged in total?"

The assistant calls `get-workout-count` and reports the number directly.

### Notes

* Returns only a count; it does not accept date filters or pagination parameters.
* Useful for estimating the total number of pages before iterating with `get-workouts` (`totalPages = ceil(count / pageSize)`).

***

## get-workout-events

Lists workout update and delete events since a given timestamp, returned newest first.

**Kind:** Read-only

### Input parameters

<ParamField query="page" type="integer" default="1">
  Page number to retrieve. Must be **≥ 1**. Defaults to `1`.
</ParamField>

<ParamField query="pageSize" type="integer" default="5">
  Number of events per page. Must be between **1** and **10** (inclusive). Defaults to `5`.
</ParamField>

<ParamField query="since" type="string" default="1970-01-01T00:00:00Z">
  ISO 8601 UTC timestamp. Only events that occurred at or after this time are returned. Defaults to `"1970-01-01T00:00:00Z"`, which returns all events in the account's history.
</ParamField>

### Example usage

> "What workouts have changed since last Monday?"

Pass the Monday date as an ISO timestamp (`since: "2025-01-20T00:00:00Z"`) and the assistant pages through events to identify updates and deletes.

### Notes

* `since` must be a valid ISO 8601 UTC timestamp string in `YYYY-MM-DDTHH:mm:ssZ` format. Invalid timestamps are rejected.
* The default `since` value of `1970-01-01T00:00:00Z` reads from the beginning of recorded history, which may return a very large result set — narrow the window in production use.
* This tool is designed for **incremental sync** scenarios (e.g., keeping a local workout cache up to date). For the current workout list, use `get-workouts` instead.
* `pageSize` is capped at **10** per page.

***

## create-workout

Creates a new completed workout in the authenticated Hevy account.

**Kind:** Write (mutation)

<Warning>
  Retrying a failed `create-workout` call **can create duplicate workouts**. Hevy does not enforce uniqueness on workout title or start time. Verify the workout was not already created (via `get-workouts`) before retrying.
</Warning>

### Input parameters

#### Top-level fields

<ParamField body="title" type="string" required>
  Workout title. Must be a non-empty string (minimum 1 character).
</ParamField>

<ParamField body="startTime" type="string" required>
  UTC start time of the workout. Must match the format `YYYY-MM-DDTHH:mm:ssZ` exactly (e.g., `"2025-01-27T09:00:00Z"`).
</ParamField>

<ParamField body="endTime" type="string" required>
  UTC end time of the workout. Must match the format `YYYY-MM-DDTHH:mm:ssZ` exactly (e.g., `"2025-01-27T10:15:00Z"`).
</ParamField>

<ParamField body="description" type="string">
  Optional free-text description for the workout. May be `null`.
</ParamField>

<ParamField body="isPrivate" type="boolean" default="false">
  Whether the workout is private on the Hevy social feed. Defaults to `false`.
</ParamField>

<ParamField body="exercises" type="array" required>
  Ordered list of exercises performed in the workout. May be supplied as a JSON array or a JSON-encoded string. Each element must conform to the exercise object shape below.
</ParamField>

#### Exercise object fields

Each object in the `exercises` array has the following fields:

<ParamField body="exerciseTemplateId" type="string" required>
  The ID of the exercise template to use. Must be a non-empty string. Discover template IDs with `get-exercise-templates` or `search-exercise-templates`.
</ParamField>

<ParamField body="supersetId" type="number">
  Numeric superset group identifier. Exercises sharing the same `supersetId` are grouped as a superset. May be `null` or omitted for non-superset exercises.
</ParamField>

<ParamField body="notes" type="string">
  Free-text notes for this exercise. May be `null` or omitted.
</ParamField>

<ParamField body="sets" type="array" required>
  Array of set objects performed for this exercise. Each set must conform to the set object shape below.
</ParamField>

#### Set object fields

Each object in an exercise's `sets` array has the following fields:

<ParamField body="type" type="string" default="normal">
  Set type. One of `"warmup"`, `"normal"`, `"failure"`, or `"dropset"`. Defaults to `"normal"`.
</ParamField>

<ParamField body="weightKg" type="number">
  Weight lifted in kilograms. Also accepted as `weight` (alias). May be `null` or omitted for bodyweight or cardio exercises.
</ParamField>

<ParamField body="reps" type="integer">
  Number of repetitions performed. May be `null` or omitted for duration-based exercises.
</ParamField>

<ParamField body="distanceMeters" type="integer">
  Distance covered in meters. Also accepted as `distance` (alias). May be `null` or omitted for non-cardio exercises.
</ParamField>

<ParamField body="durationSeconds" type="integer">
  Duration of the set in seconds. Also accepted as `duration` (alias). May be `null` or omitted for rep-based exercises.
</ParamField>

<ParamField body="rpe" type="number">
  Rate of perceived exertion. Accepted values are those recognized by the Hevy API RPE enum (e.g., `6`, `6.5`, … `10`). May be `null` or omitted.
</ParamField>

<ParamField body="customMetric" type="number">
  Custom metric value for exercises that track a non-standard measurement. Also accepted as `customMetric` (alias). May be `null` or omitted.
</ParamField>

### Example usage

> "Log today's bench press workout. I did 3 sets at 80 kg for 8 reps, starting at 7:30 AM and finishing at 8:15 AM."

The assistant calls `create-workout` with the title, UTC-formatted `startTime` and `endTime`, the bench press `exerciseTemplateId`, and the three sets filled in with `weightKg: 80` and `reps: 8`.

### Notes

* Both `startTime` and `endTime` must be **exact UTC timestamps** in `YYYY-MM-DDTHH:mm:ssZ` format. Timezone-offset formats (e.g., `+05:30`) are not accepted.
* `exerciseTemplateId` values must already exist in Hevy. Use `search-exercise-templates` to look up IDs before calling this tool.
* Set `type` defaults to `"normal"` if omitted; invalid enum values are rejected.
* Aliases `weight` / `distance` / `duration` / `customMetric` are accepted in place of their `Kg` / `Meters` / `Seconds` / `Value` counterparts for convenience; when both aliases are supplied, the explicit camelCase name takes precedence.

***

## update-workout

Replaces an existing workout in the Hevy account with a fully specified new payload. All fields are overwritten; the workout is not partially patched.

**Kind:** Write (mutation)

### Input parameters

`update-workout` accepts `workoutId` plus the complete workout payload — the same fields as `create-workout`.

<ParamField body="workoutId" type="string" required>
  The ID of the workout to replace. Must be a non-empty string. The workout must already exist in the account.
</ParamField>

All fields documented for [create-workout](#create-workout) (`title`, `startTime`, `endTime`, `description`, `isPrivate`, and `exercises`) apply here with the same types, formats, and constraints.

### Example usage

> "I recorded the wrong weight on my last squat session — fix set 2 to 100 kg instead of 90 kg."

The assistant fetches the workout with `get-workout`, modifies the relevant set's `weightKg` in memory, then calls `update-workout` with the workout's ID and the corrected full payload.

### Notes

* This is a **full replacement** (HTTP PUT). Every field in the workout — including sets you do not intend to change — must be included in the payload. Omitting optional fields may cause them to be cleared or set to API defaults.
* `update-workout` is idempotent: repeating the same call with the same payload yields the same stored state.
* The update is destructive in that it overwrites the prior workout record. Always retrieve the current workout with `get-workout` before constructing an update payload to avoid accidentally losing data.
* Use `create-workout` when logging a brand-new session; use `update-workout` only when correcting or editing an existing, known workout ID.
