Freediver
Plan freediving workouts
- Category
- Health & Wellness
- Primary Subcategory
- Endurance Sport Training Planners
Integration details
Description
Freediver Club helps athletes and coaches plan, inspect, and log freediving workouts through ChatGPT. It can read profile preferences and workout history, draft structured pool, depth, static, and supporting sessions, create or update workouts, record executed lap and rest data, and let coaches work with consenting athletes in training centers.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Endurance Sport Training Planners
- Secondary Subcategories
- None listed
- Brand
- freediver.club
- Access
- Account required
- First tracked
- 2026-04-29
- Tool count
- 10
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Freediver
Get updates when Freediver’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Endurance Sport Training Planners
View Category10 tools agents can invoke
Create a new workout for the authenticated user, or as a coach for an athlete in a training center by providing trainingCenterUuid and connectionId. The athlete must have granted coaching MCP access. Workout shape: • Top-level metadata: scheduling (scheduled_at), workout_type, optional name, and optional completion flags when explicitly relevant. Notes and RPE are the athlete's post-workout self-summary in the app—do not set them via this tool; leave them for the athlete. • instructions is the plan-level description of the session (what it is about, its goal, how to approach it). This is the field for coach/athlete plan text at the workout level, and it is kept when a workout is cloned. Set it when the plan warrants a narrative beyond the name; do not put post-session log text here (that is notes). • drills: ordered list of in-water / structured work. Omit drills entirely for schedule-only sessions (e.g. strength, sauna, stretching, recovery blocks) where the plan is just date, type, and title. How prescriptions are usually built: • One drill ≈ one block (e.g. a main set, a secondary set, or a depth line). Chain multiple drills when the session has distinct phases; use the workout name to summarize the whole day at a glance. • Optional drill name and drill/element notes are for coach-facing instructions (how to run the block, cues, equipment). Element notes explain each piece to the athlete. • Pace and duration bounds: call the user-profile tool for disciplineSpeeds—per-discipline speeds in m/s for low, normal, and high pace (user-defined where set, merged with defaults). Use them to estimate dive or swim time from distance/depth, reason about interval load, and set realistic bounds on overall workout duration when authoring or reviewing a plan. Each drill: • elements: ordered segments for a single repetition—pool lengths, depth targets, static holds, or an "other" step with notes (e.g. breath-up / protocol cues). Every rep runs the full list in order; use multiple elements when one "rep" is a composed sequence, not only a single lap or dive. • reps: how many times to repeat that full element sequence. Intervals between reps use rest_type (see below)—not gaps between individual elements inside one rep. Discipline fields — set only the field(s) that match the discipline; omit all others entirely (never set unused fields to 0): • Pool dynamics (dynamic_apnea, dynamic_apnea_with_bifins, dynamic_apnea_no_fins): set distance (m) and pace. Omit depth and time. • Static apnea: set time (seconds) and pace. Omit distance and depth. Optional static_apnea_goal: 1 = contractions (open-ended hold, omit time on this element), 4 = general timed hold (include time). Plain timed hold: omit static_apnea_goal or use 4 with time. Contractions set (two elements per rep): first element goal=1 (no time); second element goal=4 with time (e.g. 30s after contractions). At most two elements; contractions element first. • Depth (constant_weight, constant_weight_with_bifins, constant_weight_no_fins, free_immersion, hang): set depth (m) and pace. Omit distance and time. • Other: use element notes to describe the step (e.g. breath-up cues). All measurement fields are optional and should be omitted if not applicable. Rest between repetitions (same drill, after each rep except the last rep): • rest_type "fixed" — fixed_rest_time in seconds (typical for pool interval training). • rest_type "dynamic" — dynamic_rest_option: dive_time (1×), twice_dive_time (2×), three_dive_time (3×) vs dive/hold duration; common on depth sessions with repeated dives. • rest_type "free_text" — free_text_label for a custom label shown to the athlete. • rest_type null — no rest between reps. Rest between drills (after a drill, before the next): • break_time is the pause in seconds after that drill before starting the next block. Set it whenever the athlete should recover between sections (e.g. moving from a long single effort to a rep scheme, or between pool sets). The last drill does not need a following break—still set break_time on earlier drills when the plan calls for it.
createWorkout
Get workouts for athletes in the coach's training centers. Only includes athletes who have granted coaching MCP access. Respects each athlete's workout sharing date preference. Returns workouts grouped by athlete connection ID. How to read the JSON (not just raw keys): • The payload is an array of { connection_id, workouts }. Each connection_id identifies an athlete in the training center; workouts is that athlete's list for the range (most recently scheduled first). • Each workout object: uuid, scheduled_at (ISO), workout_type, optional name, completed, is_competition; optional notes and rpe are the athlete's post-workout log when filled in—not coach plan text. instructions, when present, is the plan-level description of the session (coach/athlete plan text)—distinct from notes. • pool_length_meters: the pool length used for this workout in metres (e.g. 25, 50). Always present. Use this to convert laps to distance when pool_length_meters is needed (e.g. total metres swum = laps × pool_length_meters). • drills lists prescription blocks in order; an empty array is normal for schedule-only sessions (e.g. strength, sauna, stretching) with no in-water structure. • total_distance is meters; total_apnea_time and total_workout_duration are seconds. For a session the athlete recorded, apnea time comes from the stopwatch laps in workout_state (each rep's planned time is replaced by its recorded lap sum, and a dynamic rest is derived from that recorded time); everything else—total_distance always, and apnea time for reps with no recording—is estimated from the drill structure and pace/discipline assumptions. So a planned 3:00 hold actually held 2:30 reports 150, and a contractions rep (open-ended, no planned time) reports its real hold instead of 0. • dominant_discipline: the single discipline carrying the most apnea-time volume in the workout (e.g. dynamic_apnea_with_bifins), precomputed on save. null for sessions with no apnea volume (supporting/empty workouts). Use it to tell at a glance what a workout mainly trained. • workoutTypes filter (if provided): pool — pool-training and/or pool disciplines inside drills; depth — depth-training and/or depth disciplines; static — static-only sessions; supporting — stretching, strength, other, sauna. • disciplines filter (if provided): matches workouts whose dominant_discipline equals one of the exact values (e.g. dynamic_apnea_no_fins for DNF sessions). Takes precedence over workoutTypes when both are set; never matches supporting sessions (null dominant_discipline). • countBack (if provided): returns the last N workouts counting back from endDate instead of a date window (max 20; mutually exclusive with startDate). Use it for "most recent workouts" queries without guessing a start date. On the athlete tool, N is the total across all selected athletes. workout_state (present when the athlete has started or completed the session in the app; carries the same information as the REST training-session endpoint): • flatWorkout: the workout unrolled into a flat sequence of items for execution. Each item is either an exercise or a rest, discriminated by "kind": - exercise: { kind: "exercise", drillId, repIndex, drill: { id, drill_order, name, reps, notes?, break_time?, fixed_rest_time?, dynamic_rest_option?, elements: [{ id, discipline, pace, time?, distance?, depth?, notes?, static_apnea_goal? }] } }. drillId (1-based drill order) and repIndex (1-based rep) are exactly the values to echo back to updateTrainingSession—no need to re-derive them from the plan. The embedded drill's depth/distance elements already reflect any achieved override recorded for that rep. - rest: { kind: "rest", seconds?, label?, dynamicRestOption? }. • checksum: server-computed structure hash (informational; never send one back—the server handles checksums). • poolSizeMeters: the pool length in meters for this session (same value as the sibling pool_length_meters). • states: a map of exercise key → { completed, laps: [{ elapsed, lap_end_timestamp }] }. Keys are "ex-<index>" where index is the item's position in flatWorkout. elapsed is the lap/dive/hold duration in seconds recorded by the athlete's stopwatch. lap_end_timestamp is the absolute instant that lap FINISHED (epoch milliseconds) — the moment the stopwatch lap was stopped, not when the effort began; the lap started at lap_end_timestamp − elapsed × 1000. Consecutive laps therefore give the gap between efforts: next lap's start minus this lap's lap_end_timestamp. That gap is real wall-clock for sessions the athlete recorded live in the app and for sessions auto-built from imported dive data (each dive's lap ends at its recorded end instant). It is NOT real for sessions written through updateTrainingSession: those timestamps are synthesized from the workout's scheduled time plus cumulative lap seconds, so the gaps read as zero — use the flatWorkout rest items for the breaks there. For pool disciplines convert to distance via speed (m/s) = poolSizeMeters / elapsed. For depth or static disciplines, elapsed is the total dive or hold duration. • Only exercises the athlete has started appear in states—absent keys mean that step was not started. dives (present only on depth workouts that have imported dive data): • A lightweight per-dive summary array, one row per recorded dive (so the number of dives is the array length). Each row: { dive_index, max_depth_m, dive_time_s, descent_time_s, ascent_time_s } — depth in metres, times in seconds. No sample profile, speeds, temperature or surface interval here. • For the FULL per-dive profile (per-second depth/hr/temp/vertical-speed samples, descent/bottom/ascent phase split, and fired depth alarms), call the getDiveProfiles tool with the workout uuid(s). It is heavy — request only the specific dives you need to analyse. sensors (present only when the session recorded live sensor data, e.g. a paired heart-rate strap or pulse oximeter): • One row per device: { origin, name, kinds } — origin is the system that recorded it (ble = a device paired to the phone; garmin/suunto/apple_watch = provider ingest), name is the device's user-facing name, kinds are the series it actually recorded (heartRate, spo2, …). No numbers here — this only tells you what exists. • For the values, call the getSensorSeries tool with the workout uuid(s). It returns per-series statistics (point count, time span, min/max/avg per field). The raw per-sample grid is never exposed over MCP — do not ask for it. Workout shape: • Top-level metadata: scheduling (scheduled_at), workout_type, optional name, and optional completion flags when explicitly relevant. Notes and RPE are the athlete's post-workout self-summary in the app—do not set them via this tool; leave them for the athlete. • instructions is the plan-level description of the session (what it is about, its goal, how to approach it). This is the field for coach/athlete plan text at the workout level, and it is kept when a workout is cloned. Set it when the plan warrants a narrative beyond the name; do not put post-session log text here (that is notes). • drills: ordered list of in-water / structured work. Omit drills entirely for schedule-only sessions (e.g. strength, sauna, stretching, recovery blocks) where the plan is just date, type, and title. How prescriptions are usually built: • One drill ≈ one block (e.g. a main set, a secondary set, or a depth line). Chain multiple drills when the session has distinct phases; use the workout name to summarize the whole day at a glance. • Optional drill name and drill/element notes are for coach-facing instructions (how to run the block, cues, equipment). Element notes explain each piece to the athlete. • Pace and duration bounds: call the user-profile tool for disciplineSpeeds—per-discipline speeds in m/s for low, normal, and high pace (user-defined where set, merged with defaults). Use them to estimate dive or swim time from distance/depth, reason about interval load, and set realistic bounds on overall workout duration when authoring or reviewing a plan. Each drill: • elements: ordered segments for a single repetition—pool lengths, depth targets, static holds, or an "other" step with notes (e.g. breath-up / protocol cues). Every rep runs the full list in order; use multiple elements when one "rep" is a composed sequence, not only a single lap or dive. • reps: how many times to repeat that full element sequence. Intervals between reps use rest_type (see below)—not gaps between individual elements inside one rep. Discipline fields — set only the field(s) that match the discipline; omit all others entirely (never set unused fields to 0): • Pool dynamics (dynamic_apnea, dynamic_apnea_with_bifins, dynamic_apnea_no_fins): set distance (m) and pace. Omit depth and time. • Static apnea: set time (seconds) and pace. Omit distance and depth. Optional static_apnea_goal: 1 = contractions (open-ended hold, omit time on this element), 4 = general timed hold (include time). Plain timed hold: omit static_apnea_goal or use 4 with time. Contractions set (two elements per rep): first element goal=1 (no time); second element goal=4 with time (e.g. 30s after contractions). At most two elements; contractions element first. • Depth (constant_weight, constant_weight_with_bifins, constant_weight_no_fins, free_immersion, hang): set depth (m) and pace. Omit distance and time. • Other: use element notes to describe the step (e.g. breath-up cues). All measurement fields are optional and should be omitted if not applicable. Rest between repetitions (same drill, after each rep except the last rep): • rest_type "fixed" — fixed_rest_time in seconds (typical for pool interval training). • rest_type "dynamic" — dynamic_rest_option: dive_time (1×), twice_dive_time (2×), three_dive_time (3×) vs dive/hold duration; common on depth sessions with repeated dives. • rest_type "free_text" — free_text_label for a custom label shown to the athlete. • rest_type null — no rest between reps. Rest between drills (after a drill, before the next): • break_time is the pause in seconds after that drill before starting the next block. Set it whenever the athlete should recover between sections (e.g. moving from a long single effort to a rep scheme, or between pool sets). The last drill does not need a following break—still set break_time on earlier drills when the plan calls for it.
getAthleteWorkouts
Get the FULL dive profiles for one or more depth workouts. Use this after getWorkouts / getAthleteWorkouts (which list only a lightweight per-dive 'dives' summary) when you need the detailed shape of the dives — depth curve, phase timings, depth-alarm markers, or detected propulsion strokes. Access: the workout owner, or a coach/buddy with view access; for another athlete's workout the athlete must have granted coaching MCP access. UUIDs you cannot access, or that have no imported dives, are silently omitted. Input: workoutUUIDs — an array of workout uuids (1–20). Heavy per call: each dive carries a per-second sample series, so request only the specific workouts you intend to analyse, not a whole date range. How to read the JSON: • The payload is an array of { workout_uuid, dive_profiles }. dive_profiles is that workout's dives in order. • Each dive: dive_index, started_at, discipline, max_depth_m, dive_time_s, surface_interval_s, descent_time_s, ascent_time_s, avg_descent_speed_mps, avg_ascent_speed_mps, hang_time_s, water_temp_c. • profile: the normalised per-second series [{ t, depth, hr, temp, v }] — t seconds from the dive's first sample, depth in metres (positive down), hr bpm, temp °C, v raw signed vertical speed m/s (positive down, negative up; unsmoothed — smooth it yourself if needed). • phases: turn-point split { turn_time_s, descent_time_s, bottom_time_s, ascent_time_s, time_to_20m_s } (time_to_20m_s is null when the dive never reached 20 m). • alarms: fired depth-alarm markers [{ t, depth }], aligned to the profile timeline. • strokes: detected propulsion strokes split by phase — { descent: [{ t, depth, distance_m }], ascent: [...], descent_count, ascent_count, total }, aligned to the profile timeline. distance_m is the metres the stroke propelled the athlete (depth covered until the next stroke; the last stroke reaches the apex on descent / the surface on ascent — freefall after the last descent stroke is included in it, and the entry before the first stroke is unattributed). Detection is discipline-agnostic; label the events from the dive's discipline: pulls (free_immersion), strokes (constant_weight_no_fins), kicks (constant_weight / constant_weight_with_bifins). Empty arrays mean no propulsion peaks (e.g. pure freefall or hang), not missing data.
getDiveProfiles
Get recorded sensor statistics for one or more workouts — heart rate, SpO2 and anything else a device streamed during the session. Use this after getWorkouts / getAthleteWorkouts (which list only which devices recorded, under 'sensors') when you need the actual numbers. Access: the workout owner, or a coach/buddy with view access; for another athlete's workout the athlete must have granted coaching MCP access. UUIDs you cannot access, or with no recorded series, are silently omitted. Input: workoutUUIDs — an array of workout uuids (1–20). How to read the JSON: • The payload is an array of { workout_uuid, series }. • Each series entry is one device-and-measurement pair: { origin, name, kind, points, from, to, duration_s, stats }. kind is what was measured (heartRate, spo2, …); points is the number of recorded samples; from/to are the first and last sample instants in epoch milliseconds (the same clock as workout_state lap_end_timestamp, so you can line a series up against the laps); duration_s is the recording span in seconds. • stats maps each recorded field to { min, max, avg } over its non-null values — e.g. { hr: { min: 52, max: 178, avg: 131 } } for heartRate, { spo2, pulse, pi } for an oximeter. Values are raw, in the device's own units (hr in bpm, spo2 in %); a field the device never filled in is absent. • The per-sample series itself is NOT available over MCP by design — it is thousands of points per session. Reason from the statistics and the session structure; the athlete's app renders the curve.
getSensorSeries
Returns the full Freediver Club MCP skills guide as Markdown. Call ths tool in case the skills guide is not available in the host. Call at the start of a planning or coaching session so tool usage, workout structure, pace rules, safety, and workflows are available. Read-only reference text; does not access user data.
getSkillsGuide
Get all training centers the authenticated coach manages, along with the athletes in each center who have granted coaching MCP access. Athletes who have not enabled the ALLOW_COACHING_MCP_ACCESS setting are excluded.
getTrainingCenters
Get the authenticated user's workouts within a date range (or the last N via countBack). Returns full workout details including drills, elements, and calculated totals (distance, apnea time, duration). How to read the JSON (not just raw keys): • The payload is an array of workout objects, most recently scheduled first. • Each workout object: uuid, scheduled_at (ISO), workout_type, optional name, completed, is_competition; optional notes and rpe are the athlete's post-workout log when filled in—not coach plan text. instructions, when present, is the plan-level description of the session (coach/athlete plan text)—distinct from notes. • pool_length_meters: the pool length used for this workout in metres (e.g. 25, 50). Always present. Use this to convert laps to distance when pool_length_meters is needed (e.g. total metres swum = laps × pool_length_meters). • drills lists prescription blocks in order; an empty array is normal for schedule-only sessions (e.g. strength, sauna, stretching) with no in-water structure. • total_distance is meters; total_apnea_time and total_workout_duration are seconds. For a session the athlete recorded, apnea time comes from the stopwatch laps in workout_state (each rep's planned time is replaced by its recorded lap sum, and a dynamic rest is derived from that recorded time); everything else—total_distance always, and apnea time for reps with no recording—is estimated from the drill structure and pace/discipline assumptions. So a planned 3:00 hold actually held 2:30 reports 150, and a contractions rep (open-ended, no planned time) reports its real hold instead of 0. • dominant_discipline: the single discipline carrying the most apnea-time volume in the workout (e.g. dynamic_apnea_with_bifins), precomputed on save. null for sessions with no apnea volume (supporting/empty workouts). Use it to tell at a glance what a workout mainly trained. • workoutTypes filter (if provided): pool — pool-training and/or pool disciplines inside drills; depth — depth-training and/or depth disciplines; static — static-only sessions; supporting — stretching, strength, other, sauna. • disciplines filter (if provided): matches workouts whose dominant_discipline equals one of the exact values (e.g. dynamic_apnea_no_fins for DNF sessions). Takes precedence over workoutTypes when both are set; never matches supporting sessions (null dominant_discipline). • countBack (if provided): returns the last N workouts counting back from endDate instead of a date window (max 20; mutually exclusive with startDate). Use it for "most recent workouts" queries without guessing a start date. On the athlete tool, N is the total across all selected athletes. workout_state (present when the athlete has started or completed the session in the app; carries the same information as the REST training-session endpoint): • flatWorkout: the workout unrolled into a flat sequence of items for execution. Each item is either an exercise or a rest, discriminated by "kind": - exercise: { kind: "exercise", drillId, repIndex, drill: { id, drill_order, name, reps, notes?, break_time?, fixed_rest_time?, dynamic_rest_option?, elements: [{ id, discipline, pace, time?, distance?, depth?, notes?, static_apnea_goal? }] } }. drillId (1-based drill order) and repIndex (1-based rep) are exactly the values to echo back to updateTrainingSession—no need to re-derive them from the plan. The embedded drill's depth/distance elements already reflect any achieved override recorded for that rep. - rest: { kind: "rest", seconds?, label?, dynamicRestOption? }. • checksum: server-computed structure hash (informational; never send one back—the server handles checksums). • poolSizeMeters: the pool length in meters for this session (same value as the sibling pool_length_meters). • states: a map of exercise key → { completed, laps: [{ elapsed, lap_end_timestamp }] }. Keys are "ex-<index>" where index is the item's position in flatWorkout. elapsed is the lap/dive/hold duration in seconds recorded by the athlete's stopwatch. lap_end_timestamp is the absolute instant that lap FINISHED (epoch milliseconds) — the moment the stopwatch lap was stopped, not when the effort began; the lap started at lap_end_timestamp − elapsed × 1000. Consecutive laps therefore give the gap between efforts: next lap's start minus this lap's lap_end_timestamp. That gap is real wall-clock for sessions the athlete recorded live in the app and for sessions auto-built from imported dive data (each dive's lap ends at its recorded end instant). It is NOT real for sessions written through updateTrainingSession: those timestamps are synthesized from the workout's scheduled time plus cumulative lap seconds, so the gaps read as zero — use the flatWorkout rest items for the breaks there. For pool disciplines convert to distance via speed (m/s) = poolSizeMeters / elapsed. For depth or static disciplines, elapsed is the total dive or hold duration. • Only exercises the athlete has started appear in states—absent keys mean that step was not started. dives (present only on depth workouts that have imported dive data): • A lightweight per-dive summary array, one row per recorded dive (so the number of dives is the array length). Each row: { dive_index, max_depth_m, dive_time_s, descent_time_s, ascent_time_s } — depth in metres, times in seconds. No sample profile, speeds, temperature or surface interval here. • For the FULL per-dive profile (per-second depth/hr/temp/vertical-speed samples, descent/bottom/ascent phase split, and fired depth alarms), call the getDiveProfiles tool with the workout uuid(s). It is heavy — request only the specific dives you need to analyse. sensors (present only when the session recorded live sensor data, e.g. a paired heart-rate strap or pulse oximeter): • One row per device: { origin, name, kinds } — origin is the system that recorded it (ble = a device paired to the phone; garmin/suunto/apple_watch = provider ingest), name is the device's user-facing name, kinds are the series it actually recorded (heartRate, spo2, …). No numbers here — this only tells you what exists. • For the values, call the getSensorSeries tool with the workout uuid(s). It returns per-series statistics (point count, time span, min/max/avg per field). The raw per-sample grid is never exposed over MCP — do not ask for it. Workout shape: • Top-level metadata: scheduling (scheduled_at), workout_type, optional name, and optional completion flags when explicitly relevant. Notes and RPE are the athlete's post-workout self-summary in the app—do not set them via this tool; leave them for the athlete. • instructions is the plan-level description of the session (what it is about, its goal, how to approach it). This is the field for coach/athlete plan text at the workout level, and it is kept when a workout is cloned. Set it when the plan warrants a narrative beyond the name; do not put post-session log text here (that is notes). • drills: ordered list of in-water / structured work. Omit drills entirely for schedule-only sessions (e.g. strength, sauna, stretching, recovery blocks) where the plan is just date, type, and title. How prescriptions are usually built: • One drill ≈ one block (e.g. a main set, a secondary set, or a depth line). Chain multiple drills when the session has distinct phases; use the workout name to summarize the whole day at a glance. • Optional drill name and drill/element notes are for coach-facing instructions (how to run the block, cues, equipment). Element notes explain each piece to the athlete. • Pace and duration bounds: call the user-profile tool for disciplineSpeeds—per-discipline speeds in m/s for low, normal, and high pace (user-defined where set, merged with defaults). Use them to estimate dive or swim time from distance/depth, reason about interval load, and set realistic bounds on overall workout duration when authoring or reviewing a plan. Each drill: • elements: ordered segments for a single repetition—pool lengths, depth targets, static holds, or an "other" step with notes (e.g. breath-up / protocol cues). Every rep runs the full list in order; use multiple elements when one "rep" is a composed sequence, not only a single lap or dive. • reps: how many times to repeat that full element sequence. Intervals between reps use rest_type (see below)—not gaps between individual elements inside one rep. Discipline fields — set only the field(s) that match the discipline; omit all others entirely (never set unused fields to 0): • Pool dynamics (dynamic_apnea, dynamic_apnea_with_bifins, dynamic_apnea_no_fins): set distance (m) and pace. Omit depth and time. • Static apnea: set time (seconds) and pace. Omit distance and depth. Optional static_apnea_goal: 1 = contractions (open-ended hold, omit time on this element), 4 = general timed hold (include time). Plain timed hold: omit static_apnea_goal or use 4 with time. Contractions set (two elements per rep): first element goal=1 (no time); second element goal=4 with time (e.g. 30s after contractions). At most two elements; contractions element first. • Depth (constant_weight, constant_weight_with_bifins, constant_weight_no_fins, free_immersion, hang): set depth (m) and pace. Omit distance and time. • Other: use element notes to describe the step (e.g. breath-up cues). All measurement fields are optional and should be omitted if not applicable. Rest between repetitions (same drill, after each rep except the last rep): • rest_type "fixed" — fixed_rest_time in seconds (typical for pool interval training). • rest_type "dynamic" — dynamic_rest_option: dive_time (1×), twice_dive_time (2×), three_dive_time (3×) vs dive/hold duration; common on depth sessions with repeated dives. • rest_type "free_text" — free_text_label for a custom label shown to the athlete. • rest_type null — no rest between reps. Rest between drills (after a drill, before the next): • break_time is the pause in seconds after that drill before starting the next block. Set it whenever the athlete should recover between sections (e.g. moving from a long single effort to a rep scheme, or between pool sets). The last drill does not need a following break—still set break_time on earlier drills when the plan calls for it.
getWorkouts
Record what actually happened in a session (the executed training-session state) without touching the planned drills — to change the plan itself, use updateWorkout instead. Typical use: after reading wearable data (e.g. Garmin), write the actual depths/distances, rests, laps, and completion for a planned workout. The executed session is INDEPENDENT of the plan: the achieved depth/distance and the real breaks you send here override the plan values and never modify it. Never call updateWorkout to reflect what was performed. Access: the workout owner, or a coach/buddy with assist access. When writing another athlete's session, the athlete must have granted coaching MCP access. How the input works: • flatWorkout (optional): the executed sequence as a flat list. Rest items are written literally ({ kind: "rest", seconds and/or label }) — use them to record the actual breaks taken (they do NOT inherit the plan's rest). Exercise items are references ({ kind: "exercise", drillId, repIndex }): drillId is the 1-based position of the drill in the workout's plan, repIndex the 1-based repetition number; the server expands each reference into the full drill from the current plan. Add an optional distance on an exercise item to record the achieved measurement for that dive/rep — reached depth (m) for depth disciplines (CWT/CWTB/CNF/FIM/hang), swum distance (m) for pool disciplines (DYN/DYNb/DNF) — overriding the plan value for that item only; omit it to keep the plan value. distance cannot be set on static or "other" exercises. Omit flatWorkout to keep the existing executed sequence (or the plan's default flattening). • states (optional): a map of exercise key → { laps, completed? }. Keys are "ex-<index>" where index is the item's position in flatWorkout (the one you send in this call, or the effective one if you omit flatWorkout). laps are plain elapsed seconds per lap/dive/hold (on read they appear under states["ex-N"].laps[].elapsed). You send durations only — the server derives each lap's lap_end_timestamp from the workout's scheduled time plus the cumulative lap seconds within that exercise, so on read those instants mark lap ends but are not real wall-clock times and the gaps between them are not the real rests. completed defaults to true. Provided keys overwrite that exercise's recording; absent keys are preserved (per-key merge), so incremental writes are safe. • poolSizeMeters (optional): pool length in meters used for this session. • Checksums are handled automatically by the server — never construct or send one. Depth sessions with per-dive surface intervals: reps of the SAME drill render as one grouped "N reps" block sharing a single rest, so the real breaks between those dives disappear. Before recording such a session, reshape the plan with updateWorkout so every dive is its own 1-rep drill (reps: 1, rest_type: null, break_time = the real surface interval after that dive, no break_time on the last). Keep nominal depth targets rounded to whole meters — the reached depth goes on the executed distance override, which accepts decimals. Then every executed exercise uses repIndex 1 and its own drillId. Worked example — an executed depth session. Dives 29.5m (1:21), 60m (2:00), 60m (2:09), 64m (2:06); surface intervals 1317s, 2001s, 1269s. Plan reshaped via updateWorkout into 4 one-rep CWT drills (depths 20/60/60/60, break_time 1317/2001/1269/none). Then send: flatWorkout: [ { kind: "exercise", drillId: 1, repIndex: 1, distance: 30 }, { kind: "rest", seconds: 1317 }, { kind: "exercise", drillId: 2, repIndex: 1, distance: 60 }, { kind: "rest", seconds: 2001 }, { kind: "exercise", drillId: 3, repIndex: 1, distance: 60 }, { kind: "rest", seconds: 1269 }, { kind: "exercise", drillId: 4, repIndex: 1, distance: 64 } ], states: { "ex-0": { laps: [81] }, "ex-2": { laps: [120] }, "ex-4": { laps: [129] }, "ex-6": { laps: [126] } } This records CWT 30m/60m/60m/64m with the actual breaks and dive times, each dive rendering as its own block. Returns the merged training-session state in the same workout_state shape that getWorkouts returns.
updateTrainingSession
Update an existing workout. Only provided fields are changed. The user must be the workout owner or the coach who created it. When editing an athlete's workout, the athlete must have granted coaching MCP access. Workout shape: • Top-level metadata: scheduling (scheduled_at), workout_type, optional name, and optional completion flags when explicitly relevant. Notes and RPE are the athlete's post-workout self-summary in the app—do not set them via this tool; leave them for the athlete. • instructions is the plan-level description of the session (what it is about, its goal, how to approach it). This is the field for coach/athlete plan text at the workout level, and it is kept when a workout is cloned. Set it when the plan warrants a narrative beyond the name; do not put post-session log text here (that is notes). • drills: ordered list of in-water / structured work. Omit drills entirely for schedule-only sessions (e.g. strength, sauna, stretching, recovery blocks) where the plan is just date, type, and title. How prescriptions are usually built: • One drill ≈ one block (e.g. a main set, a secondary set, or a depth line). Chain multiple drills when the session has distinct phases; use the workout name to summarize the whole day at a glance. • Optional drill name and drill/element notes are for coach-facing instructions (how to run the block, cues, equipment). Element notes explain each piece to the athlete. • Pace and duration bounds: call the user-profile tool for disciplineSpeeds—per-discipline speeds in m/s for low, normal, and high pace (user-defined where set, merged with defaults). Use them to estimate dive or swim time from distance/depth, reason about interval load, and set realistic bounds on overall workout duration when authoring or reviewing a plan. Each drill: • elements: ordered segments for a single repetition—pool lengths, depth targets, static holds, or an "other" step with notes (e.g. breath-up / protocol cues). Every rep runs the full list in order; use multiple elements when one "rep" is a composed sequence, not only a single lap or dive. • reps: how many times to repeat that full element sequence. Intervals between reps use rest_type (see below)—not gaps between individual elements inside one rep. Discipline fields — set only the field(s) that match the discipline; omit all others entirely (never set unused fields to 0): • Pool dynamics (dynamic_apnea, dynamic_apnea_with_bifins, dynamic_apnea_no_fins): set distance (m) and pace. Omit depth and time. • Static apnea: set time (seconds) and pace. Omit distance and depth. Optional static_apnea_goal: 1 = contractions (open-ended hold, omit time on this element), 4 = general timed hold (include time). Plain timed hold: omit static_apnea_goal or use 4 with time. Contractions set (two elements per rep): first element goal=1 (no time); second element goal=4 with time (e.g. 30s after contractions). At most two elements; contractions element first. • Depth (constant_weight, constant_weight_with_bifins, constant_weight_no_fins, free_immersion, hang): set depth (m) and pace. Omit distance and time. • Other: use element notes to describe the step (e.g. breath-up cues). All measurement fields are optional and should be omitted if not applicable. Rest between repetitions (same drill, after each rep except the last rep): • rest_type "fixed" — fixed_rest_time in seconds (typical for pool interval training). • rest_type "dynamic" — dynamic_rest_option: dive_time (1×), twice_dive_time (2×), three_dive_time (3×) vs dive/hold duration; common on depth sessions with repeated dives. • rest_type "free_text" — free_text_label for a custom label shown to the athlete. • rest_type null — no rest between reps. Rest between drills (after a drill, before the next): • break_time is the pause in seconds after that drill before starting the next block. Set it whenever the athlete should recover between sections (e.g. moving from a long single effort to a rep scheme, or between pool sets). The last drill does not need a following break—still set break_time on earlier drills when the plan calls for it.
updateWorkout
Get the authenticated user's profile preferences: IANA timezone, preferred UI language, and resolved discipline speeds. All speed values in disciplineSpeeds are in meters per second (m/s): low, normal, and high pace per freediving discipline (merged with defaults when the user has not customized a discipline). Use disciplineSpeeds when planning or estimating workout duration from distance, depth, and pace (same basis as app totals).
user-profile
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Freediver alternatives on ChatGPT?
As of 2026-09-28, Freediver competes with AI Endurance, COROS, Eixo Run, Endorphins Running, Endurance Planner, Fitness AI Connector, Flow State, Joules, Leo - Running Coach, PaceBeats, PaceKeeper AI, Pelaris, Propusher, rit.run, rit.run, Tredict, Vertical in ChatGPT Endurance Sport Training Planners, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.