MCP App Store
by KeenEthics
Acta Fit icon

Acta Fit

By Jacob Bergam

Get New App Alerts

Overview

Acta Fit is a strength and conditioning log for iPhone and Apple Watch. Connect it to ask about your own training data in plain language. What you can ask: - Your recent workouts: dates, exercises, sets, reps, loads and volume. - Progress on any lift: top sets and estimated one-rep-max trends over time. - Training stats for the week, month or year: workout count, sets, volume and weeks active. - Heart rate and power for any session, including per-set and per-interval breakdowns, time in zone and normalized power, whenever your Apple Watch or another Apple Health source recorded them. - Your plans, saved workout templates and training maxes. What it can propose: - A training plan, a single workout, or a new exercise. Proposals land in the Acta Fit app, where you review and accept or dismiss them. Nothing in your log changes until you accept. Requirements: the Acta Fit iPhone app with an account and AI sync turned on. Weights are shown in your own unit.

Tools

create_exercise

ChatGPT
Register ONE new exercise name for use in future create_training_plan / create_workout_template proposals. Rare and deliberate: plans should be built from the user's existing exercises. Two-step check: the first call returns the user's complete exercise vocabulary — READ IT and check whether any entry is the SAME MOVEMENT under a different name (e.g. 'Stationary Bike' duplicates 'Cycling'; 'OHP' duplicates 'Overhead Press') — and only when nothing matches, call again with confirm: true. Nothing is created immediately: the name becomes usable in proposals, and the exercise is created in the user's library (badged as new on the review screen) only when they accept a plan that uses it. Strength movements only — plans cannot schedule cardio yet.

create_training_plan

ChatGPT
Propose a multi-day training plan for the user. This only files a proposal: it lands in the user's inbox in the Acta Fit app, where they review it and accept or dismiss it; nothing in their data changes until they accept. Strength training only: a template is exercises × sets × reps × load, so plans cannot schedule cardio (bike, run, swim, row or intervals) yet. Leave each cardio weekday a rest day and put the session in the plan notes, never as a weight exercise; then tell the user plainly, in your own words, that plans can't hold cardio days yet, that you left those days as rest days and that the sessions are in the plan notes. Before proposing: (1) if the plan builds on the user's routine, call get_workout_templates and copy their templates faithfully, accessories included; (2) use exercise names exactly as get_workout_templates / get_exercise_history / get_training_maxes return them (unknown names are rejected with close-match suggestions; register a genuinely new movement with create_exercise first); (3) give working sets a load via weight (in weights_unit, the user's own unit) or percentageOfMax (resolved against the user's training max at review time), never both; (4) pick progressionAlgorithmRaw deliberately: linear5x5 for 5×5-style linear progression, gzclp for GZCLP, none for a manual plan. When a template re-uses the name of one the user already has, include every exercise, every warm-up set (setTypeRaw: 'warmup') and every superset grouping (supersetGroup) from the saved version: the server compares the two and rejects a proposal that leaves any out, listing what is missing; only when the user explicitly asked for a slimmer version, resubmit with confirm_omissions: true. Days reference templates by exact name from this proposal's templates array; a day without templateName is a rest day (weekday 1 = Sunday). An identical resubmit returns the existing pending proposal; pass replaces_id to revise one of your own pending proposals. The user's inbox holds at most 5 pending proposals. When it is full the call files nothing and returns error pending_limit_reached with the pending proposals (id, title, oldest first): don't stop at telling the user the inbox is full; offer to replace the pending proposal most like this one (or else the oldest), naming it by title, and only if they agree, call again with the same arguments plus replaces_id set to its id. The replaced proposal stays in the inbox history. Hard safety limits are enforced server-side and cannot be overridden: a proposal that exceeds them (sets per exercise or week, training days, load above the user's recent best or training max, back-to-back heavy leg days, and the like) is rejected with error hard_limit_violation and a list of violations, each with the field path, the limit and a suggested fix; apply every fix and resubmit.

create_workout_template

ChatGPT
Propose ONE standalone workout (a template: exercises × sets × reps × load) for the user's library, with no plan or weekly schedule. Use it when the user asks for a single workout ('make me a push day'); use create_training_plan for a multi-day program. This only files a proposal: it lands in the user's inbox in the Acta Fit app, where they review it and tap Save to Library; nothing in their data changes until then, and saving adds a new template beside any existing one with the same name, which stays as it is. Afterwards it can be started from the library and read back via get_workout_templates. The rules of create_training_plan's templates apply: strength only (a workout cannot hold cardio or intervals yet, and they never go in as weight exercises; put them in the notes and tell the user so); exercise names exactly as the read tools return them (unknown names are rejected with close-match suggestions; register a genuinely new movement with create_exercise first); a load per working set via weight (in weights_unit, the user's unit) or percentageOfMax, never both; and when the name matches a template the user already has, include every exercise, warm-up set (setTypeRaw: 'warmup') and superset grouping (supersetGroup) from the saved version, because the server rejects a proposal that leaves any out and lists what is missing; confirm_omissions: true only when the user explicitly asked for a slimmer version. An identical resubmit returns the existing pending proposal; pass replaces_id to revise one of your own pending proposals. The user's inbox holds at most 5 pending proposals. When it is full the call files nothing and returns error pending_limit_reached with the pending proposals (id, title, oldest first): don't stop at telling the user the inbox is full; offer to replace the pending proposal most like this one (or else the oldest), naming it by title, and only if they agree, call again with the same arguments plus replaces_id set to its id. The replaced proposal stays in the inbox history. Poll get_plan_inbox for the outcome. Hard safety limits are enforced server-side and cannot be overridden: a proposal that exceeds them (sets per exercise or week, training days, load above the user's recent best or training max, back-to-back heavy leg days, and the like) is rejected with error hard_limit_violation and a list of violations, each with the field path, the limit and a suggested fix; apply every fix and resubmit.

get_exercise_history

ChatGPT
Sets over time for one exercise (name match is case-insensitive; 'squat' matches 'Back Squat'), for progress and PR analysis. Incomplete sets are dropped; warmups are kept and flagged. Weights are in the user's unit (see weights_unit), newest session first. With no 'from', covers the 90 days before 'to' (or before today).

get_plan

ChatGPT
The user's training plans: weekly schedule (weekday → workout name), start date, progression style, and any upcoming date-specific changes. The active plan is what the user follows today.

get_plan_inbox

ChatGPT
Status of proposals sent via create_training_plan or create_workout_template (format tells them apart: track.plan.v1 = plan, track.workout.v1 = single workout): pending (awaiting the user's in-app review), imported (accepted — a plan is then readable via get_plan, a workout via get_workout_templates, after the next sync), failed/dismissed (status_detail says why), superseded, expired. List mode returns metadata only; pass proposal_id with include_payload for one full proposal.

get_profile

ChatGPT
The user's profile: preferred units (format outputs accordingly — all stored weights are kilograms regardless), account email, and member-since date.

get_training_maxes

ChatGPT
The user's training maxes (reference weights for percentage-based programming), one per lift, in the user's unit (see weights_unit), with when each was last updated.

get_training_stats

ChatGPT
Aggregate training stats for a rolling window ending now: workout count, sets, total volume (user's unit per weights_unit; completed non-warmup sets), weeks active, average workouts/week, top exercises by volume with estimated 1RMs (Epley). Periods: week, month, 3months, year, all.

get_workout

ChatGPT
Full detail for one workout session by its session_key (from list_workouts): the user's notes when written (their own account of the session — weigh it above the numbers), every exercise and set (weights in the user's unit per weights_unit/key suffix, warmup/working type and completion flagged per set), effort score, heart-rate summary (avg/max/min bpm and time_in_zone when recorded), benchmark scores. Health-imported cardio sessions may also carry distance, elevation, power, speed, cadence, and start-of-workout weather — present only when available, in the user's unit per weights_unit/distance_unit and the matching key suffix (_km/_mi, _m/_ft, _kmh/_mph, _c/_f). A streams block means a heart-rate and/or power sample stream exists: use get_workout_metrics for per-set and per-interval heart rate and power, totals (work in kJ, normalized power), and the raw series.

get_workout_metrics

ChatGPT
Heart-rate and power analysis for one workout session (session_key from list_workouts). Returns session totals (heart_rate: avg/max/min bpm, time_in_zone; power: avg/max/min W, normalized_w, work_kj) and a segments timeline that splits the session into work and rest blocks from the rest timer, labelling each work block with the logged exercise + set (set_alignment says how reliable that labelling is) and giving that block's own avg/max/min heart rate and power plus work_kj — this is the per-set / per-interval breakdown. Everything is computed from the full sample streams; set include_series true to also get the raw series as [seconds_from_start, value] pairs (bucket-averaged to max_points). notes explains any missing data: a session without a heart-rate source has heart_rate null, and power is only ever present when the workout's Apple Health source wrote a power series (Apple Watch rides and runs do; Peloton and Strava imports generally do not), so most strength sessions and many imported rides have power null while their heart rate is complete. Weights on set labels are in the user's unit (weights_unit).

get_workout_templates

ChatGPT
The user's SAVED workout templates with their complete exercise lists — including accessory work — plus per-set targets (weights in the user's unit per weights_unit). ALWAYS read these before proposing a plan that modifies or builds on the user's existing routine: reproduce their real templates faithfully rather than reconstructing generic versions from the template name.

list_workouts

ChatGPT
List the user's workout sessions, newest first — summaries only (date, title, status, duration, completed sets, volume, avg_heart_rate when a heart-rate source covered the session, effort_score when the user rated the session, and notes when the user wrote any). effort_score is the user's own session RPE on a 0–10 scale (CR-10) — scan it across sessions for fatigue and readiness trends; a session without the key simply wasn't rated. notes are the user's OWN WORDS about that session (pain, what they skipped and why, energy) — read them before judging a session by its numbers, and carry their implications into any plan you propose. Volume counts completed non-warmup sets; completed_sets includes warmups. All weights are in the USER'S OWN unit — the response's weights_unit field and _kg/_lb key suffixes say which; use their unit in every reply. Dates are ISO-8601 UTC. Use get_workout with a returned session_key for full sets. Archived sessions are excluded unless include_archived is true.

ping

ChatGPT
Connectivity check: echoes input and confirms the caller is authenticated.

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

Similar Apps