TrainingPeaks manager skill proposal

Objective

Create a trainingpeaks-manager skill that is the single, unified interface for all TrainingPeaks calendar operations.

The skill has two responsibilities:

  1. Direct TP activity management — reading, creating, updating, moving, and deleting activities in TrainingPeaks via the MCP server, including structured workout construction, field mapping, and activity type selection.
  2. Sync orchestration — keeping the local athlete calendar at athlete/calendar/ and the live TP calendar aligned, handling bidirectional changes, and maintaining cross-reference IDs between the two systems.

This skill absorbs and replaces the existing trainingpeaks-activity-creator skill. That skill's responsibilities — field mapping, activity type selection, structured workout creation, and MCP-based creation and editing — are folded directly into trainingpeaks-manager. There will be no separate creation skill after this implementation. The trainingpeaks-activity-creator skill should be retired once the manager is validated.

This proposal is athlete-agnostic. The path pattern and sync logic must work for any athlete username without hard-coded references to a specific athlete or sport.

Scope boundary

This proposal covers:

  • how the skill creates, updates, moves, and deletes TP activities directly via the MCP server
  • field mapping from local calendar fields to TP activity fields
  • activity type selection, structured workout construction, and title conventions
  • how the skill reads the local calendar and the TP calendar
  • how the skill determines what needs to change during a sync
  • how the skill updates local calendar files to record TP activity IDs
  • how the skill uses local Id fields to correlate local items with TP activities
  • rules for add, revise, move, and delete operations in both directions
  • the retirement of trainingpeaks-activity-creator and absorption of its responsibilities

This proposal does not cover:

  • when the skill runs (scheduling via cron or other trigger is out of scope)
  • what activities should exist or whether a given training plan is correct
  • how planning decisions are made upstream
  • athlete-facing messaging or communication after sync
  • the calendar-manager skill, which remains the canonical local-only calendar editor

The trainingpeaks-manager is only responsible for the sync process itself. External triggers tell it when to run.

Why this skill is needed

The local calendar layer at athlete/calendar/ is now the canonical per-day planning object model. TrainingPeaks is the external coaching and training management system where athletes and coaches interact with daily activities.

Without a unified skill, these problems exist:

  • activities exist in local files but never appear on the athlete's TP calendar
  • activities added or revised directly in TP are not reflected in local files
  • there is no stable cross-reference between a local Id and a TP activity ID
  • manual syncing is error-prone and does not scale across athletes or dates
  • two separate skills (trainingpeaks-activity-creator and any future sync skill) overlap significantly in TP knowledge, MCP usage, and field mapping logic, creating duplication and maintenance burden

The trainingpeaks-manager closes these gaps by combining direct TP activity management with bidirectional sync in a single, well-tested skill that can be triggered externally on any schedule.

Design principles

1. The local calendar is the source of truth for planned content

The content of a calendar item — its title, objective, workout plan, duration, intensity, and other field values — is authored and maintained in the local calendar file.

When the same item exists in both the local calendar and TP, the local file content is authoritative for plan details unless the intent of the sync operation is explicitly to pull from TP.

2. TP activity IDs and local IDs are both durable reference fields

Once an item is created in TP, the TP activity ID must be written back into the corresponding local calendar item as a TrainingPeaks ID field.

Once an item is created locally, its local Id value must be written into the TP activity, either as a note, a custom field, or whichever TP field the MCP server exposes for free-form reference text. This cross-reference is how the skill correlates the two representations across future sync operations.

3. Correlation drives all sync decisions

Before performing any create, update, or delete operation, the skill must attempt to correlate:

  • local calendar items by their Id field and TrainingPeaks ID field
  • TP activities by their activity ID and any embedded local Id reference

An item with a known TrainingPeaks ID in the local file has already been created in TP and should be updated, not re-created. An item in TP that contains a local Id in its reference field is already correlated and should not be duplicated. An item in TP with no local correlation may be a TP-native item and should be treated as a pull candidate.

4. All TP communication goes through the MCP server

The skill must not attempt to access TrainingPeaks via any direct API call, web request, or undocumented path. Every read, create, update, and delete operation against TrainingPeaks must go through the TrainingPeaks MCP server.

5. Local file edits use the calendar file format contract

When the skill writes back into a local calendar file — to add a TrainingPeaks ID field, update a field value, or record a TP-originated item — it must follow the calendar file format defined in the athlete calendar activity proposal.

The skill must not reformat, reorder, or restructure calendar files beyond what is needed to add or update a specific field.

6. The skill does not plan or decide

The trainingpeaks-manager applies sync operations. It does not decide whether an activity should exist, whether the training plan is appropriate, or whether a given TP activity should be adopted as a local calendar item.

When the sync direction or intent is ambiguous, the skill should surface the conflict rather than silently choosing a resolution.

Sync operations

Push: local calendar item → TrainingPeaks

Trigger condition: a local calendar item has no TrainingPeaks ID field, or that field is empty.

Steps:

  1. Read the local calendar item fields and content sections.
  2. Map local fields to the TP activity schema (see Field mapping section).
  3. Select the correct TP activity type based on Kind and Discipline (see Activity type selection section).
  4. Build a structured workout when the session has clearly defined intervals; use a plain description for endurance or recovery sessions.
  5. Create the activity in TP via the MCP server, including the luca tag and the local Id embedded in the TP reference field.
  6. Write the returned TP activity ID into the local file as TrainingPeaks ID: <id>.

Tagging rule: every TP activity created by the manager must include the luca tag. This allows the athlete to filter their TP calendar to show only coach-created items.

Failure handling:

  • If the MCP server returns an error, log the error and do not modify the local file.
  • Do not retry silently; surface the error for external review.

Pull: TrainingPeaks activity → local calendar

Trigger condition: a TP activity exists for a date within scope and has no corresponding local calendar item (identified by the absence of a matching local Id or TrainingPeaks ID in the local file for that date).

Steps:

  1. Read the TP activity fields via the MCP server.
  2. Map TP fields to the local calendar item schema.
  3. Create a new local calendar item in the appropriate YYYY-MM-DD.md file using the calendar file format contract.
  4. Write the TP activity ID into the new local item as TrainingPeaks ID: <id>.
  5. Write the local Id of the newly created item back into the TP activity reference field via the MCP server.

Ambiguity rule: if the local date file already exists and has other activities, append the new item without disturbing existing items. If the date file does not exist, create it.

Update: local changes → TrainingPeaks

Trigger condition: a local calendar item has a TrainingPeaks ID field with a known value, and one or more local fields have changed since the last sync (determined by comparing local field values to the current TP activity state retrieved from the MCP server).

Steps:

  1. Fetch the current state of the TP activity using the MCP server and the stored TrainingPeaks ID.
  2. Diff the local item against the TP activity state.
  3. Apply only the fields that differ via a TP update call through the MCP server.
  4. Do not overwrite TP fields that are not represented in the local calendar item schema.

Update: TP changes → local calendar

Trigger condition: a TP activity with a known local Id correlation has changed in TP since the last known sync state, and the intent is a pull-direction update.

Steps:

  1. Fetch the current state of the TP activity via the MCP server.
  2. Identify which local fields differ from the TP activity state.
  3. Update the relevant fields in the local calendar file, preserving all other local content.
  4. Do not overwrite local fields that have no corresponding TP representation.

Delete: remove from TrainingPeaks

Trigger condition: a local calendar item is marked for deletion from TP, or the item has been removed from the local calendar and a TrainingPeaks ID was previously recorded.

Steps:

  1. Confirm the TP activity ID to be deleted.
  2. Delete the activity via the MCP server.
  3. On success, remove the TrainingPeaks ID field from the local calendar item, or confirm that the local item has already been removed.

Delete: remove from local calendar when TP activity is deleted

Trigger condition: a TP activity that previously had a local correlation has been deleted from TP.

Steps:

  1. Locate the corresponding local calendar item using the stored TrainingPeaks ID.
  2. Remove or flag the local item as appropriate, following the calendar-manager archive rules if the item is on a past date.

Field mapping

The skill must maintain a stable mapping between local calendar fields and TP activity fields as exposed by the MCP server.

Mapping guidelines:

  • Title → TP activity title
  • Kind and Discipline → TP activity type or sport (see Activity type selection below)
  • Duration → TP planned duration
  • Distance → TP planned distance
  • Planned time → TP scheduled start time, if TP supports it and a time is set
  • Intensity → TP description or structured workout field, as appropriate
  • Objective, Workout plan, and Notes → TP description or notes field, concatenated and clearly labeled
  • Id → TP reference or notes field, prefixed with a stable marker such as coachluca-id: so it can be parsed back reliably

The exact field names and capabilities available in TP must be determined from the MCP server schema at runtime. The skill should read available TP fields from the MCP server before mapping and should not assume field availability.

Activity type selection

The skill must select the correct TP activity type so the calendar icon and sport classification are accurate from creation.

Guidelines:

  • Use the local Discipline field as the primary signal, cross-referenced with Kind.
  • Prefer specific TP types — Road, MTB, CX, Strength — over generic fallbacks when the discipline is clear.
  • Do not use redundant title prefixes such as Road - , MTB - , or Strength - when the activity type already communicates that information.
  • Use clear, descriptive session titles. Strength sessions should use specific names such as Lower-body strength session or Post-threshold strength session, not vague shorthand.
  • Do not set a planned start time unless one is explicitly provided in the local calendar item.
  • Do not add zone explanations or educational descriptions of zones in TP activity descriptions. Assume athletes already know their zones.

Structured workouts

For sessions with clearly defined interval structure — threshold, VO2, tempo sets — the skill should create a structured workout in TP rather than a plain description when the MCP server supports it.

For endurance, recovery, or loosely defined sessions, a well-written plain description is sufficient.

The workout structure should preserve the planned session intent and athlete-facing wording from the local calendar item. Do not reinterpret or simplify the prescribed structure.

Conflict resolution

A conflict occurs when both the local item and the TP activity have changed since the last known correlated state.

Default conflict rule:

  • Treat the local calendar as authoritative for plan content unless the operation was explicitly initiated as a TP-to-local pull.
  • Surface any conflict where TP contains content that is not present in the local file, so it is not silently discarded.

The skill should not silently discard changes from either side. If a conflict cannot be resolved deterministically, the skill should report the conflict and wait for guidance rather than choosing arbitrarily.

Scope of a sync run

When triggered, the skill should operate on a defined date scope. The scope should be provided by the trigger or calling context. Common scopes:

  • a single date
  • a date range (e.g., the next 14 days)
  • all dates with unsynced local items
  • all TP activities for a given date range that have no local correlation

The skill should not assume a default scope if none is provided. The calling process must specify the scope explicitly.

Local calendar file changes

When the skill writes back into a local calendar file, it must:

  • locate the correct activity by its Id or heading
  • add or update only the fields it is responsible for (TrainingPeaks ID and any fields updated from a TP pull)
  • preserve all other content in the file, including other activities, sections, and formatting
  • follow the field ordering convention from the activity schema: reference fields such as TrainingPeaks ID should appear after the core activity fields in the field block

Error states

The skill should handle and surface the following error conditions:

  • MCP server unavailable or returning errors
  • TP activity not found for a stored TrainingPeaks ID (may have been deleted externally)
  • local calendar file not found for an expected date
  • field mapping failure when a required TP field is not available
  • conflict detected between local and TP state with no clear resolution
  • duplicate correlation detected (two local items with the same TrainingPeaks ID, or two TP activities with the same local Id)

In all cases, the skill should report the error with enough context for a human or calling process to investigate, and should not apply partial changes that leave the system in an inconsistent state.

What the skill does not do

  • It does not decide when to run. Scheduling is handled externally by a cron job, remote trigger, or other mechanism.
  • It does not decide what activities should exist in the calendar. Planning is upstream of this skill.
  • It does not communicate with the athlete. Athlete messaging is handled by separate skills.
  • It does not perform direct API calls to TrainingPeaks. All TP operations go through the MCP server.
  • It does not reformat or restructure local calendar files beyond the specific fields it manages.
  • It does not override the calendar-manager skill for local-only calendar operations.

Relationship to existing skills

Skill Responsibility
calendar-manager Local-only calendar operations: create, edit, delete, move calendar items in athlete/calendar/
trainingpeaks-activity-creator Creating, updating, moving, and deleting activities in TrainingPeaks via MCP; structured workout construction; field mapping and activity type selection
trainingpeaks-manager Sync orchestration: determines what needs to change, delegates TP creation to trainingpeaks-activity-creator, handles pull operations, writes cross-reference IDs back into local files

The trainingpeaks-manager is a sync orchestrator, not a TP creation tool. For push operations it delegates to trainingpeaks-activity-creator rather than re-implementing creation logic. For local file operations it reads and minimally updates files rather than replacing the calendar-manager role.

Implementation recommendations

Phase 1: push only

Implement push direction first:

  1. Read local calendar items that have no TrainingPeaks ID.
  2. Delegate each item to trainingpeaks-activity-creator, passing the local calendar item as the source of truth.
  3. Write the returned TP activity ID back into the local file as TrainingPeaks ID.
  4. Write the local Id into the TP activity reference field via the MCP server.

This gives the highest value quickly and establishes the cross-reference contract before pull and conflict logic is needed. Delegating to trainingpeaks-activity-creator also means the push path benefits immediately from that skill's existing field mapping, structured workout logic, and tested MCP patterns.

Phase 2: pull and update

Implement pull direction and update operations once the push direction is stable and the cross-reference pattern is proven.

Phase 3: conflict detection

Add explicit conflict detection once both directions are operating and edge cases from real usage are understood.

Resolved decisions

  • All TP communication must use the TrainingPeaks MCP server. No direct API access.
  • Push-direction activity creation must be delegated to trainingpeaks-activity-creator. The manager does not re-implement creation logic.
  • Every TP activity created by the manager must have the luca tag applied, so the athlete can filter to coach-created items on their calendar.
  • The local Id must be written into TP as a stable reference so future sync runs can correlate without depending on title matching alone.
  • The TP activity ID must be written into the local file as TrainingPeaks ID after every successful push.
  • The skill does not decide its own run schedule. It only executes when triggered.
  • When conflict resolution is ambiguous, surface the conflict rather than silently choosing a winner.
  • The skill is athlete-agnostic. The username is a runtime input, not a hard-coded assumption.

Recommendation

Adopt the trainingpeaks-manager skill as the canonical sync layer between local athlete calendar files and the TrainingPeaks calendar.

Implement in three phases — push first, then pull and update, then conflict detection — so each phase can be validated before adding complexity.

Keep the skill narrowly scoped to sync mechanics. Scheduling, planning decisions, and athlete communication remain the responsibility of separate processes.