Skip to main content
Glama

Save and assign a training plan

save_training_plan
DestructiveIdempotent

Save a previewed plan draft, once the coach or athlete has confirmed it. Side effects with save_mode='save_and_assign' (default, athletes only): every workout of the draft is scheduled on the athlete's calendar, the plan becomes their primary plan, a Garmin workout sync is queued when the athlete has Garmin connected, and when a coach saves for an athlete the athlete gets an in-app notification. save_mode='template_only' saves a Training Plan Template and changes no calendar; it is the only mode for group drafts, whose template assign_group_plan then assigns. Pass exactly one of athlete_id or group_id. A draft is single-use, expires 24 hours after drafting and only the account that drafted it can save it, so a repeated save changes nothing. previous_primary_plan, when present, is the earlier primary plan, which stays active but demoted; overlapping_workouts counts its upcoming workouts on days the new plan also schedules.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "draft_id": "<draft_id>"
    },
    "name": "save_training_plan"
  }
}

Input Schema

NameRequiredDescriptionDefault
draft_idYesdraft_id from create_training_plan or a draft edit by this account (single-use, expires 24 hours after drafting).
group_idNoA group id from get_team_overview. Pass exactly one of athlete_id or group_id.
plan_nameNoName for the saved plan; defaults to the draft's.
save_modeNosave_and_assign: schedule the plan for the athlete; template_only: save a template only (the only mode for group drafts).save_and_assign
athlete_idNoThe athlete's user id (get_current_user, get_coach_athletes or find_athlete). Pass exactly one of athlete_id or group_id.
start_dateNoYYYY-MM-DD; defaults to the draft's start date.
long_run_preferenceNoLong-run day; omit to keep the plan's own long-run day.
training_days_per_weekNoTraining days per week, 2-7.

Output Schema

NameRequiredDescriptionDefault
errorNo
weeksNo
statusNo
messageNo
privacyNoPresent when the athlete's settings withhold data.
group_idNo
warningsNo
next_stepNoWhat can be done next, for example after a failure.
plan_nameNo
save_modeNo
assign_urlNo
athlete_idNo
start_dateNo
next_cursorNoReads the next page; null on the last page.
reason_codeNo
total_weeksNo
subject_kindNo
template_urlNo
user_contentNoFields in this result that people wrote.
weeks_returnedNo
plan_instance_idNo
training_plan_idNo
truncated_fieldsNoLists cut to fit one response: rows returned and total.
generated_contentNoFields in this result that NexRex's AI wrote.
session_definitionsNoSessions that several rows of this result share by session_ref.
content_block_fieldsNoColumn names of every content_blocks row, nested blocks rows included.
overlapping_workoutsNoUpcoming workouts of the previous primary plan on shared days.
previous_primary_planNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedOutput schema / $defs / Activity / properties / content_blocks / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "items": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "integer"
      -          },
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "boolean"
      -          },
      -          {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "string"
      -                },
      -                {
      -                  "type": "integer"
      -                },
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "boolean"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          {
      -            "$ref": "#/$defs/LocalizedText"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "type": "array"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "items": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "boolean"
      +          },
      +          {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "integer"
      +                },
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "boolean"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "$ref": "#/$defs/LocalizedText"
      +          },
      +          {
      +            "items": {
      +              "type": "array"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "type": "array"
      +    },
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / $defs / Activity / properties / content_blocks / description
      Previous value: -"Interval rows; each row's values follow content_block_fields."New value: +"Workout steps as rows whose values follow content_block_fields; an interval's blocks value is its nested steps as rows in the same columns."
    • changedOutput schema / properties / content_block_fields / description
      Previous value: -"Column names of every content_blocks row."New value: +"Column names of every content_blocks row, nested blocks rows included."
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag destructiveHint=true and idempotentHint=true; the description goes well beyond them by enumerating each side effect of save_and_assign: calendar scheduling of every workout, primary-plan promotion, queued Garmin sync, and an in-app athlete notification. It also explains the non-obvious idempotency semantics ('a repeated save changes nothing') and clarifies that template_only touches no calendar.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The paragraph is front-loaded with the core action and the default mode's effects, so nothing critical is buried. It is dense to the point of feeling crowded — the return-value explanation and the group-draft aside sit mid-sentence — but no sentence is pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter mutation with a destructive hint, the description covers prerequisites, mode selection, side effects, idempotency, and account scoping, while the output schema covers return values. An agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so a 3 is the floor, but the description adds real meaning: the default and athlete-only restriction of save_mode, the group-draft-only nature of template_only, and what previous_primary_plan and overlapping_workouts represent. It leaves start_date, long_run_preference, and training_days_per_week to the schema, which is acceptable given full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The definition names a specific verb and resource ('Save a previewed plan draft') and immediately delimits it against the drafting step and the group-template path that assign_group_plan handles. An agent can distinguish it from create_training_plan, assign_group_plan, and enroll_training_plan without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the precondition (coach or athlete has confirmed the preview), the selection rule ('Pass exactly one of athlete_id or group_id'), and the alternative routing for group drafts ('it is the only mode for group drafts, whose template assign_group_plan then assigns'). Failure conditions — single-use draft, 24-hour expiry, only the drafting account may save — are spelled out explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources