MCP App Store
by KeenEthics

Overview

Simma turns swimming, running and cycling data into coaching for triathletes and endurance athletes. It reads activities from Garmin, computes the numbers a triathlon coach actually uses — form calibrated to each athlete's own history, per-sport training status across swim, bike and run, pace and stroke detail down to the lap — and gives ChatGPT the finished picture rather than raw files. For coaches. Whether you coach triathletes, runners, cyclists or swimmers, ask who on your roster needs attention this week and why. Open one athlete and get three weeks of sessions bucketed by week, their load against their own baseline, race goals with days to go, the linked training plan, and pre-computed flags for the things worth a message. Draft that message in your own voice, save it, and send it from Simma so replies thread back into the same conversation. Keep private notes per athlete that steer every future draft. Every number is computed by Simma; ChatGPT writes the words. For athletes. Ask how your triathlon training is going and get an honest read against your own history, not a generic scale. Look up any swim, ride or run in detail, find the sessions where you faded or negative-split, set and track race goals, link a training plan, and message your coach — or, if you are self-coached, get the same analysis Simma gives a coach. What it does not do. Simma never sends anything on your behalf without an explicit confirmation step, and read tools are marked read-only so ChatGPT can use them freely. Tools that overwrite a setting, delete a goal or end a coaching relationship are marked destructive so ChatGPT asks before running them. Sending a message is gated twice: the draft is shown to you in full and must be approved before it goes. You need a Simma account; new users can create one during sign-in. Activity data comes from Garmin Connect, linked from the Simma web app. Your training history loads within a few minutes of linking, as long as historical data is allowed on Garmin's consent page.

Tools

check_athlete_workout

ChatGPT
Check a workout written in Simma's workout format against one athlete's pool and thresholds. Returns each mistake with the path to it, or the workout read back as plain lines with its totals and whether it can be sent to that athlete's watch. Changes nothing.

check_my_workout

ChatGPT
Check a workout written in Simma's workout format against the athlete's own pool and thresholds. Returns each mistake with the path to it, or the workout read back as plain lines with its totals and whether it can be sent to a watch. Changes nothing.

check_send_safety

ChatGPT
Report which safety gates are active for send_draft in this client. Run it before relying on send_draft: the strongest gate — asking the coach directly before each send — only exists if the client supports MCP elicitation, and the server cannot know that until a client connects. By default this reads what the client declared, which is a claim rather than proof. Pass probe: true to actually raise a throwaway confirmation prompt and find out whether it works. A client can advertise the capability and still fail to show anything, and only a probe catches that.

create_goal

ChatGPT
Add a goal for the athlete: an event with a date and one target per discipline. A goal with one target takes that discipline; more than one makes it a multi-discipline goal. Each target needs a distance or a time. Confirm with the coach before calling this.

create_my_goal

ChatGPT
Add a goal for the athlete: an event with a date and one target per discipline. A goal with one target takes that discipline; more than one makes it a multi-discipline goal. Each target needs a distance or a time. Confirm with the athlete before calling this.

delete_goal

ChatGPT
Remove a goal permanently. Prefer update_goal with status completed or archived when the goal happened or was abandoned — that keeps the history the context builder reads. Delete only for mistakes, and confirm with the coach first.

delete_my_goal

ChatGPT
Remove a goal permanently. Prefer update_my_goal with status completed or archived when the goal happened or was abandoned — that keeps the history the context builder reads. Delete only for mistakes, and confirm with the athlete first.

discard_draft

ChatGPT
Delete a draft that was never sent. Use it to clear a draft the coach decided against, or one you created and no longer need — otherwise it stays in the thread indefinitely. Drafts only. A message that has been sent cannot be deleted, and should not be: removing it would not unsend the email, but it would break the routing that delivers the athlete's reply back into the thread and erase the record of what was actually said.

find_my_sessions_by_shape

ChatGPT
Every session in a window with its pacing shape, plus a roll-up. Answers "which of my swims faded in the main set this month" or "am I negative-splitting more often" from summaries Simma computed when each activity was saved — no lap data is read or averaged here. Two views per session. mainSet is the longest segment and is what a coach means by "did you fade". session is every lap including warm-up and cool-down. Prefer mainSet; mention session only when the two disagree and it matters. Shapes: negative_split (back half faster by >2%), even (within -2..+3%), faded (+3..8%), faded_hard (>8%). fadePercent is positive when they slowed. structure: opening_burst or two_paced means the set had two regimes and the shape was judged on the steady block; do not describe a two-paced set as fading. lapsExcludedAsDeviceErrors counts laps faster than physically possible that were set aside: a miscounting watch, not the athlete. Sessions with too few laps to judge are listed with shape null.

find_sessions_by_shape

ChatGPT
Every session in a window with its pacing shape, plus a roll-up. Answers questions like "which swims faded in the main set this month" or "is she negative-splitting more often" from summaries Simma computed when each activity was saved — no lap data is read or averaged here. Two views per session. mainSet is the longest segment (a swim's main set, the ride itself) and is what a coach means by "did they fade". session is every lap including warm-up and cool-down, so a structured swim often reads faded there while the main set was even or negative. Prefer mainSet; mention session only when the two disagree and it matters. Shapes: negative_split (back half faster by >2%), even (within -2..+3%), faded (+3..8%), faded_hard (>8%). fadePercent is positive when they slowed. paceVariationPercent is lap-to-lap consistency. lapSource: splits means the laps were derived from the pace series at the stated distance because no lap button was pressed — say so if you quote a lap number. Sessions with too few laps to judge are listed with shape null so you can see they existed; do not read anything into them. structure: opening_burst or two_paced means the set had two regimes — sprints then steady, or fast/easy alternating — and the shape was judged on the steady block; rawShape is what a naive whole-set split would say. Do not describe a two-paced set as fading. lapsExcludedAsDeviceErrors counts laps faster than physically possible that were set aside before judging: a miscounting watch, not an athlete.

get_activity_detail

ChatGPT
Full detail for one activity, including every lap and the split structure. Large series (GPS traces, heart-rate and pace graphs, elevation profiles, stroke analytics) are summarised rather than inlined. Use this to discuss a specific session. Values are metric. The document carries an imperial copy of each display tile, which is dropped here because it is the same data converted — it was a third of a ride's payload. Check the coach's or athlete's preferredUnits (get_coach_profile, get_athlete_profile) and convert when speaking to someone who uses imperial; do not report kilometres to a coach who works in miles.

get_activity_trace

ChatGPT
One processed trace of an activity as a table ready to chart: heart_rate (bpm over time), elevation (elevation, distance, grade and speed over time), pace (minutes per km for every 100 m), cadence (steps per minute running, revolutions per minute cycling), power (watts, rides and runs on a power-capable watch), stroke_rate (a pool swim's strokes, stroke rate, distance per stroke and speed for every length, or an open-water swim's stroke rate over time), elevation_segments (each climb, descent and flat with distance, gain, speed, heart rate and pace) or stroke_analytics (each swim lap with set, stroke, pace per 100 m and any stroke features the watch app records). columns names each value in a row and units says what it is in, once. Rows are as fine as one answer can hold: resolution says how many points Simma has and which were returned; segment and lap tables are never thinned but continue from nextFromSec when long. For full resolution on part of a long session, pass fromSec and toSec. available lists the traces this activity has. These are Simma's processed series computed from the watch file, not the file itself. The route itself (GPS) is not shared with assistants. Use with the activity detail: its laps share this clock. Leave laps flagged suspect out of pace. Leave activityId out for the athlete's most recent activity.

get_athlete_context

ChatGPT
The richest single view of an athlete, and the right starting point before writing anything to them. Returns three weeks of activity bucketed by week with per-sport volume, training load with 7-day deltas and trend, per-sport training status, goals with days-to-event, the linked training plan, and pre-computed notable flags. Every number here was computed by Simma against this athlete's own history. Treat the flags and figures as established fact: do not re-derive averages, recompute percentages, or second-guess a severity. A flag carries a machine name, a severity, the sentence a coach would say, and the values behind it — and sometimes a context line that changes the reading entirely, such as a load spike that is a return from a break rather than overreaching. Read the context line before characterising a flag. Prefer this over assembling your own picture from list_athlete_activities.

get_athlete_physiology

ChatGPT
Sleep, HRV, resting heart rate and stress for one athlete. Daily physiology from the athlete's Garmin watch: nightly HRV, sleep (duration, stages, Garmin's sleep score), resting heart rate and all-day stress, one row per calendar date, plus a summary that compares the last 7 days with the athlete's own window. Read coverage first: it says how many nights actually carry a reading, and a watch not worn to bed produces nothing. The readings are measurements against the person's own recent days, not medical findings; report them as such and do not diagnose. Garmin's Health API reaches back about 30 days, so the window is capped there in practice.

get_athlete_profile

ChatGPT
One athlete's profile and coaching relationship: name, contact, preferred units, pool length, self-rated ability by sport, and threshold values (swim/run pace, cycling power) that Simma's load model scores against. Also returns any linked Google training plan and a summary of the last 12 weeks of activities. Use this for who the athlete is; use get_training_status for how they are going.

get_athlete_stats

ChatGPT
Aggregate statistics and training form for one athlete over a window, including fitness/fatigue/form history and active goals. Use for trends over weeks rather than individual sessions.

get_coach_inbox

ChatGPT
Every athlete conversation with at least one message, most recent first, with the last message and unread count for each. Answers "who is waiting on me" across the whole roster in one call, rather than get_messages per athlete.

get_coach_profile

ChatGPT
The signed-in coach's own record: name, business name, public slug, invite code, and the voice settings Simma applies when drafting athlete emails (tone of voice, coaching instructions, sign-off). Read these before helping write anything so the wording matches what Simma itself would send.

get_messages

ChatGPT
Recent coach/athlete message thread, newest first. Useful for what has already been said before drafting anything new.

get_my_activity_detail

ChatGPT
Full detail for one activity, including every lap and the split structure. Large series (GPS traces, heart-rate and pace graphs, elevation profiles, stroke analytics) are summarised rather than inlined; get_my_activity_trace returns them to chart (the GPS route is not shared). For analysis of a session, also fetch the traces in traces.recommended and combine them. Values are metric. Check preferredUnits from get_my_profile and convert when speaking to someone who uses imperial.

get_my_activity_trace

ChatGPT
One processed trace of an activity as a table ready to chart: heart_rate (bpm over time), elevation (elevation, distance, grade and speed over time), pace (minutes per km for every 100 m), cadence (steps per minute running, revolutions per minute cycling), power (watts, rides and runs on a power-capable watch), stroke_rate (a pool swim's strokes, stroke rate, distance per stroke and speed for every length, or an open-water swim's stroke rate over time), elevation_segments (each climb, descent and flat with distance, gain, speed, heart rate and pace) or stroke_analytics (each swim lap with set, stroke, pace per 100 m and any stroke features the watch app records). columns names each value in a row and units says what it is in, once. Rows are as fine as one answer can hold: resolution says how many points Simma has and which were returned; segment and lap tables are never thinned but continue from nextFromSec when long. For full resolution on part of a long session, pass fromSec and toSec. available lists the traces this activity has. These are Simma's processed series computed from the watch file, not the file itself. The route itself (GPS) is not shared with assistants. Use with the activity detail: its laps share this clock. Leave laps flagged suspect out of pace. Leave activityId out for the most recent activity.

get_my_context

ChatGPT
The richest single view of the athlete's own training, and the right starting point for any question about how it is going. Three weeks of activity bucketed by week with per-sport volume, training load with 7-day deltas and trend, per-sport training status, goals with days-to-event, the linked training plan, and pre-computed notable flags. Every number was computed by Simma against this athlete's own history. Treat the flags and figures as established fact: do not re-derive averages, recompute percentages, or second-guess a severity. A flag carries a machine name, a severity, the sentence a coach would say, and the values behind it — and sometimes a context line that changes the reading entirely. Read the context line before characterising a flag. This is the athlete's own view: their coach's private notes are not in it and cannot be requested through this server.

get_my_messages

ChatGPT
Messages the athlete has received from their coach, newest first. Useful for what has already been said before replying.

get_my_physiology

ChatGPT
The athlete's own sleep, HRV, resting heart rate and stress. Daily physiology from the athlete's Garmin watch: nightly HRV, sleep (duration, stages, Garmin's sleep score), resting heart rate and all-day stress, one row per calendar date, plus a summary that compares the last 7 days with the athlete's own window. Read coverage first: it says how many nights actually carry a reading, and a watch not worn to bed produces nothing. The readings are measurements against the person's own recent days, not medical findings; report them as such and do not diagnose. Garmin's Health API reaches back about 30 days, so the window is capped there in practice.

get_my_profile

ChatGPT
The signed-in athlete's own record: name, preferred units, pool length, self-rated ability by sport, the threshold values (swim/run pace, cycling power or speed) Simma's load model scores against, body mass, whether the thresholds are locked against auto-estimation, and the ids of their coaches. Start here. Everything else on this server is about this person.

get_my_progress

ChatGPT
Aggregate statistics and training form over a window: fitness, fatigue and form history, distance comparisons, and sport-specific statistics. Use for trends over weeks rather than individual sessions.

get_my_training_status

ChatGPT
Per-sport training status for the athlete: form score and zone, trend, detected pattern, days since last activity, session count and flags. Simma's own training-load model — prefer it over inferring load from raw activities.

get_sign_out_instructions

ChatGPT
How to sign this assistant out of Simma, or switch to a different Simma account. Nothing is changed by calling this; it returns the steps and a sign-out link. Use it when the person asks to log out, disconnect, or sign in as someone else.

get_training_status

ChatGPT
Per-sport training status for one athlete: form score and zone, trend, detected pattern, days since last activity, session count and flags. This is Simma's own training-load model — prefer it over inferring load from raw activities.

get_workout_format

ChatGPT
The rules and worked examples for Simma's workout format: a sport, then an ordered list of steps and repeat blocks, each step with an intent, one length and at most one target. Read this before writing a workout to check or send. Use it to turn a session from a training plan, or one you have designed with the person, into a structured workout a watch can run.

join_coach

ChatGPT
Join a coach's squad with the invite code they gave the athlete. From then on that coach reads the athlete's training and can message them. If the athlete already has a coach of their own, Simma refuses and returns switchRequired with the current coach named and what leaving them means. Entering a second code almost always means changing coach, so put that to the athlete plainly: the current coach loses access, and their notes and any plan they linked go with them. Only with the athlete's explicit yes call again with replace: true; the athlete is asked to confirm directly where the client can do that, and the switch joins the new coach before removing the old so nothing can leave them coachless. Joining a coach from the Simma house account needs no confirmation; it simply happens.

leave_coach

ChatGPT
Disconnect from one of the athlete's coaches. That coach loses access to the athlete's training, and their notes and any plan they linked go with the relationship; the athlete's own activities and goals stay. With no other coach left, the athlete lands on Simma's house coach account automatically. The house coach itself cannot be left. Cannot be undone from here: rejoining needs the coach's invite code. Get the athlete's explicit agreement first; where the client supports it they are also asked directly and the call stops if they decline.

list_athlete_activities

ChatGPT
List an athlete's activities, newest first, trimmed to summary fields. Prefer a date window (weeks/months/days) over paging. Use get_activity_detail for the full breakdown of a single session.

list_athlete_goals

ChatGPT
An athlete's goals — event name, discipline, date, days until event, target time and notes. Use alongside training status to judge whether load suits the time to race.

list_athletes

ChatGPT
List the coach's athletes with their current training status, last activity, active goals and unread message count. Start here — it returns the athleteId needed by every other tool. Includes a per-athlete status such as overreaching, monitor, disengaged, quiet, welcome-back or recovering. Quiet means past their own usual gap between sessions with nothing this week — due, not yet disengaged. Paged: returns up to limit athletes (default 50) and a nextCursor when there are more. Pass it back as cursor to continue; a page can be shorter than the limit and still carry a cursor, so keep going until nextCursor is absent. Most rosters fit in one page.

list_my_activities

ChatGPT
The athlete's activities, newest first, trimmed to summary fields. Prefer a date window (weeks/months/days) over paging. Use get_my_activity_detail for the full breakdown of a single session.

list_my_coaches

ChatGPT
Who coaches this athlete, with specialty and when they connected. An athlete with no coach of their own is attached to Simma's house coach account, which will appear here; that account can read their training data, and the athlete should know that.

list_my_goals

ChatGPT
The athlete's goals — event name, discipline, date, target time and notes. Use alongside training status to judge whether load suits the time to race.

remove_athlete

ChatGPT
End the coaching relationship with an athlete. They keep every activity and goal and land on Simma's house coach account; what goes is this coach's access to their training, the coach's private notes on them, and any training plan linked for them. The message thread stays stored but is no longer reachable from this roster. Cannot be undone from here: the athlete would need to join again with the coach's invite code. Get the coach's explicit agreement naming the athlete first; where the client supports it the coach is also asked directly and the call stops if they decline. Never remove several athletes from one approval.

reply_to_coach

ChatGPT
Send a message from the athlete to their coach, into the same thread the coach's emails arrive from. This is the one action on this server that makes anything visible to another person: nothing the athlete says to you reaches Simma or their coach except what goes through here. Read the exact text back to the athlete and get their explicit agreement before calling this — pass confirm: true only once they have said yes to those words. Where the client supports it, the athlete is also asked directly in a prompt showing the message; if they decline there, nothing is sent. Sending cannot be undone. Pass coachId only when the athlete has more than one coach; list_my_coaches gives the ids.

save_draft

ChatGPT
Store a message you have written to an athlete as a draft. Nothing is sent — the draft appears in Simma where the coach can read, edit and send it, and it is what send_draft takes. Read get_coach_profile first: the coach's tone of voice, coaching instructions and sign-off are what Simma itself writes with, and a draft that ignores them will not sound like them. Ground the content in get_athlete_context rather than in your own reading of the raw numbers. Returns the stored draft including the sk that send_draft needs.

send_draft

ChatGPT
Send a saved draft to the athlete as a real email, immediately. This cannot be undone or recalled, and it arrives under the coach's name — the athlete has no way to tell it was written with an assistant. Show the coach the exact subject and body and get their explicit agreement before calling. Do not send on a vague instruction, and never batch sends across several athletes from a single approval. Where the client supports it, the coach is also asked to confirm directly and the send stops if they decline. confirmSubject and confirmBody must match the stored draft exactly, so a stale or mistaken sk cannot send a different message than the one that was approved. Take all three values from save_draft or get_messages rather than from memory.

send_workout_to_athlete_watch

ChatGPT
Send a workout in Simma's workout format to one athlete's Garmin watch, on the coach's instruction. The workout is added to the athlete's Garmin workout library, where they pick it on the watch; it is not scheduled on a date, and nothing already in Garmin is changed. Check it first and read the outline back to the person in plain words. Where the client supports it they are also asked directly, and the call stops if they decline. If Garmin refuses, its own message is returned.

send_workout_to_my_watch

ChatGPT
Send a workout in Simma's workout format to the athlete's own Garmin watch. The workout is added to the athlete's Garmin workout library, where they pick it on the watch; it is not scheduled on a date, and nothing already in Garmin is changed. Check it first and read the outline back to the person in plain words. Where the client supports it they are also asked directly, and the call stops if they decline. If Garmin refuses, its own message is returned.

update_athlete_notes

ChatGPT
Set the coach's private notes on an athlete, or the specialty the coach works with them on. Notes are the coach's own memory of the athlete — training background, constraints, what they respond to — and are included in get_athlete_context, so what you write here shapes future drafts. notes replaces the whole text: read get_athlete_profile first and carry forward what should stay.

update_athlete_profile

ChatGPT
Set an athlete's thresholds, ability levels, units, pool length, name, body mass or date of birth. Only the fields you pass change. Thresholds are what every training-load number is scored against, so a wrong one reshapes the athlete's whole history: read get_athlete_profile first, state the old and new value to the coach, and confirm before calling this. Units are the ones a coach speaks in — pace as M:SS, speed in km/h — and are converted to what Simma stores. Cycling threshold power comes from a power meter (95% of best 20-minute power is the usual estimate); threshold speed is the fallback for riders without one and is the whole basis of their load, so set it with care. Body mass only affects the climbing term of the speed-based cycling estimate; it is safe to ask the athlete for. ftpLocked stops Simma's own auto-estimation from overwriting a threshold the coach has set deliberately. Birthdate is worth asking for: without it every heart-rate zone is derived from a default age of 40. It changes zones on activities processed from now on, not ones already stored.

update_coach_profile

ChatGPT
Edit the signed-in coach's own profile: business name, public slug, and the voice settings Simma applies when drafting athlete emails (tone of voice, coaching instructions, sign-off). Only the fields you pass change; pass at least one. Read get_coach_profile first for the current values and confirm the change with the coach before calling this — the voice settings shape every draft Simma writes for them from then on. signOff is rendered verbatim at the end of each email; use a newline to separate the closing phrase from the name. The slug must be unique across coaches — a 409 means it is already taken.

update_goal

ChatGPT
Edit one of the athlete's goals: rename it, move the date, change the discipline or targets, add notes, or mark it completed or archived. Only the fields you pass change. Read list_athlete_goals first for the goalId and the current values, and confirm the change with the coach before calling this — it writes straight to the athlete's record. targets replaces the whole list, so include every target you want to keep. Distances are metres as a string; times are H:MM:SS.

update_my_goal

ChatGPT
Edit one of the athlete's goals: rename it, move the date, change the discipline or targets, add notes, or mark it completed or archived. Only the fields you pass change. Read list_my_goals first for the goalId and the current values, and confirm the change with the athlete before calling this. targets replaces the whole list, so include every target you want to keep. Distances are metres as a string; times are H:MM:SS.

update_my_profile

ChatGPT
Set the athlete's own thresholds, ability levels, units, pool length, name, body mass or date of birth. Only the fields you pass change. Thresholds are what every training-load number is scored against, so a wrong one reshapes their whole history: read get_my_profile first, state the old and new value, and confirm with the athlete before calling this. Units are the ones a person speaks in — pace as M:SS, speed in km/h — and are converted to what Simma stores. ftpLocked stops Simma's own auto-estimation from overwriting a threshold set deliberately, such as one from a lab test. Birthdate is worth asking for: without it every heart-rate zone is derived from a default age of 40. It changes zones on activities processed from now on, not ones already stored.

check_athlete_workout

Claude

check_my_workout

Claude

check_send_safety

Claude

create_goal

Claude

create_my_goal

Claude

delete_goal

Claude

delete_my_goal

Claude

discard_draft

Claude

find_my_sessions_by_shape

Claude

find_sessions_by_shape

Claude

get_activity_detail

Claude

get_activity_trace

Claude

get_athlete_context

Claude

get_athlete_physiology

Claude

get_athlete_profile

Claude

get_athlete_stats

Claude

get_coach_inbox

Claude

get_coach_profile

Claude

get_messages

Claude

get_my_activity_detail

Claude

get_my_activity_trace

Claude

get_my_context

Claude

get_my_messages

Claude

get_my_physiology

Claude

get_my_profile

Claude

get_my_progress

Claude

get_my_training_status

Claude

get_sign_out_instructions

Claude

get_training_status

Claude

get_workout_format

Claude

join_coach

Claude

leave_coach

Claude

list_athlete_activities

Claude

list_athlete_goals

Claude

list_athletes

Claude

list_my_activities

Claude

list_my_coaches

Claude

list_my_goals

Claude

remove_athlete

Claude

reply_to_coach

Claude

save_draft

Claude

send_draft

Claude

send_workout_to_athlete_watch

Claude

send_workout_to_my_watch

Claude

sign_out

Claude

update_athlete_notes

Claude

update_athlete_profile

Claude

update_coach_profile

Claude

update_goal

Claude

update_my_goal

Claude

update_my_profile

Claude

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

109

Tools

3

Prompts

ChatGPT, Claude

Platforms

Works with

ChatGPT
Claude

Data refreshed daily