speediance-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| SPEEDIANCE_MCP_HOME | No | Set SPEEDIANCE_MCP_HOME to use a different folder for the Speediance data directory. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| check_connectionA | Verify the Speediance login is live. Call this FIRST in a session, before any other tool, and stop if it reports connected:false — relay its message (the user must sign in again). A merely expired token is renewed silently when the password was remembered. |
| get_calendarA | What's scheduled and trained in a month ( |
| get_session_detailA | The actual per-exercise log — sets, reps and weight per movement — for ONE completed session.
|
| get_heart_rateB | Second-by-second heart rate for a watch-paired session: average, max, min and a series (downsampled to at most 600 points). available:false when no watch recorded it. |
| get_training_statsA | Totals between two dates (YYYY-MM-DD, inclusive): gym sessions, strength sessions, training minutes, calories, volume and energy — for questions like "how was my week?". |
| get_athlete_snapshotA | Everything needed before planning: profile (bodyweight, age, watch), the coaching memory (active facts grouped as constraints{hard, soft} / preferences / goals / observations / conflicts, preferences, ★preferred / ⊘avoided exercises, owned equipment) and recent sessions, plus otherActivities imported from the phone health app (off-machine work — include it in load). Check memory.facts.constraints.hard before building any workout and respect it; raise any memory.facts.conflicts with the user rather than picking one. memory.facts.legacyUnreviewed holds old free-form facts not yet curated: they may still bind — treat injury ones as hard constraints until curated, and curate them promptly with the user. |
| get_strength_profileB | Per movement trained recently: estimated 1RM (Epley) from its best set, that set, and how the top weight moved across the window. Scans up to the 10 most recent weighted sessions. |
| compare_sessionsB | Compare a session with an earlier one, per movement: top weight, total reps and volume deltas. previous_training_id=0 picks the most recent earlier session that shares a movement. |
| suggest_loadA | Suggest a working weight for |
| get_muscle_balanceA | Which muscles the recent training actually loaded, and how balanced it was. Spreads each weighted set's volume over the muscles the library says a movement works:
a MAIN muscle takes the full volume, an ASSISTING muscle half. Attributed totals
therefore exceed the weight actually lifted — they are shares of attention, not a
decomposition of load. Timed and level work (Vita, planks, rowing) carries no volume
and is reported as
|
| list_exercisesA | Search the Speediance exercise library. Filters: name words ( |
| get_exerciseB | One movement's details: muscles, equipment, whether it's unilateral (one side at a time — matters when building workouts), form description and cues, image and video. |
| mark_exerciseA | Mark a movement ★preferred, ⊘avoided, or clear it ("none"). Identify it by group_id, or by
|
| list_accessoriesA | Speediance's accessory catalog (bars, handles, rope, benches, AeroRow...), deduplicated by name,
each flagged |
| get_exercise_historyA | EVERY time the user has done ONE movement, oldest -> newest: the "how is my bench press going?" tool. Give the name as the user says it, or a groupId. If several exercises match, nothing is fetched and the reply is {needsPick:true, matches:[...]} — ask which one. One entry per training DAY (same-day sessions combined): topWeight, volume, and minWeight when the day had a range. |
| list_my_workoutsA | The user's saved custom workout templates. Use a template's |
| get_workoutB | A template's full prescription: exercises in order, each set's reps (or seconds), weight, Vita level, side and rest. Weights are in displayUnit. |
| create_workoutA | Create a custom workout template. |
| update_workoutA | Edit a template in place (an edit never uses a new slot). |
| delete_workoutA | Permanently delete a custom template, by |
| schedule_workoutA | Put a saved template (by |
| unschedule_workoutC | Take a scheduled template off a day (YYYY-MM-DD). |
| browse_programsA | Speediance's official multi-week programs. Without program_id, lists programs (filtered by
|
| get_preferencesA | The coaching memory: goal, training days, session length, load anchors, owned equipment,
unusable_equipment (gear they own but CANNOT use — never plan a movement needing it),
★preferred / ⊘avoided exercises, and the ACTIVE curated facts grouped as |
| set_preferencesA | Update structured preferences (only the fields given change). load_anchors maps group_id -> a known working weight in displayUnit and is MERGED into the saved anchors (other anchors are kept); a weight of null or 0 removes that anchor. owned_equipment is a list of accessory names from list_accessories (it replaces the saved list). unusable_equipment names gear the user OWNS but cannot use (an injury, a bench they can't lie on): movements needing it are hidden from list_exercises and must never be planned. Free-text facts go in remember_fact instead. |
| remember_factA | Save ONE durable training fact (max 600 characters — split longer ones; nothing is truncated) and tell the user you saved it. kind: constraint (a rule a workout must obey — needs severity: hard = never violate, soft = avoid if possible) | preference (a weight on exercise choice) | goal (a target) | observation (a dated finding, no forward authority). category: injury | equipment | schedule | body | nutrition | note. scope: optional context such as "location:tampa-hotel". supersedes: ids this fact replaces (they are archived in the same write) — use it for corrections and updates instead of adding a second version. expires_days: only for temporary things ("travelling next week" ~7). source: "user" when the user stated it directly, else "inferred" (default). If a near-identical active fact exists nothing is saved and the near-match comes back (saved=false): re-send with supersedes=[its id] if the new one replaces it. Don't store bodyweight/unit (Speediance knows) or load numbers (use set_preferences). |
| forget_factA | Archive a fact that no longer applies (ids come from get_preferences |
| list_factsA | The audit surface for the curated facts, oldest first, with each fact's status, supersedes / supersededBy chain, source and legacy flag. Default: active facts only. include_archived=true returns the full history (superseded, forgotten, expired and legacy facts). Filter by kind (constraint | preference | observation | goal) or category (injury | equipment | schedule | body | nutrition | note). |
| import_factsA | Bulk-save facts (up to 200), e.g. to curate the legacy facts. Each item is an object with the same fields as remember_fact: text, kind, category, and optional severity, scope, supersedes, expires_days, source. Every single-write rule applies to every item, in order (an item is also deduped against items accepted earlier in the batch). Returns {accepted, deduped: [{input, matched_existing_id}], rejected: [{input, reason}], superseded: [ids], dryRun}. dry_run=true returns the identical report and writes nothing — use it first, show the user, then run it for real. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 29 tools
Most tools have clearly distinct purposes (workout CRUD, calendar, analytics, library, fact management). Minor overlaps exist: schedule_workout with add=false duplicates unschedule_workout, and get_athlete_snapshot overlaps get_preferences/get_training_stats, but descriptions explicitly clarify the boundaries. An agent can reliably tell tools apart.
All 29 tools use a consistent snake_case verb_noun pattern (list_my_workouts, get_session_detail, create_workout, remember_fact, etc.). No camelCase or mixed-convention outliers. Predictable and readable throughout.
29 tools is heavy for the rubric's ideal range, though the server spans several genuinely broad domains (workout CRUD, calendar/sessions, analytics, exercise library, and a full fact/memory subsystem). Each tool is defensible, but the surface is large enough to feel sprawling, and the fact subsystem alone consumes five tools.
Coverage is exceptional: full workout CRUD plus scheduling, calendar and session detail, heart rate, multiple analytics tools, complete exercise-library browse/detail/mark/history, accessories, preferences get/set, and a full fact lifecycle (remember/forget/list/import with audit and supersede chains). No obvious dead ends for the stated coaching purpose.