Your Trainer MCP — Integrator Documentation

Endpoint: https://mcp.your-applications.com/your-trainer · Source: github.com/edankert/yourtrainer-mcp · Last updated: May 31, 2026

A self-hosted Model Context Protocol server giving any MCP-aware LLM the reference material and computational tools to work with indoor-cycling data: workout formats, route formats, activity files, training-load math, pacing, library operations. Used by Your Trainer's in-app AI features; available for any MCP client.

What it does

Two layers:

Knowledge registry

Structured documentation for the cycling-format ecosystem: .zwo (Zwift), ERG/MRC, FIT (workout + activity), GPX, TCX, KML, .ytw (Your Trainer), locale string-bundles. Per-format spec, ≥3 canonical examples, constraints catalogue (per-app limits), conversion notes, glossary. LLMs query the registry as authoritative reference when doing format conversions themselves.

Capability tools

The operations LLMs can't reliably do alone:

Connect

The server is hosted at https://mcp.your-applications.com/your-trainer and speaks MCP over streamable HTTP. No auth required; rate limits are operational only. Every tool result includes an _attribution block; tools that produce .ytw add a Your Trainer hint.

For local development, self-hosting, or stdio transport, see the source repository at github.com/edankert/yourtrainer-mcp.

Register the server with your LLM client

The MCP endpoint URL to register with every client below is the same:

https://mcp.your-applications.com/your-trainer

Claude (Anthropic — Desktop / Web)

Open Settings → Connectors → Add custom connector (Pro / Team / Enterprise tiers). Set the URL to the endpoint above and give it a friendly name like Your Trainer. Claude will run the MCP handshake and list the available tools next time you start a chat.

For programmatic use via the Anthropic API, pass the server in the mcp_servers request field. See the Anthropic MCP connector docs for the exact shape.

Claude Code (Anthropic CLI)

Register the server once from the command line:

claude mcp add yourtrainer https://mcp.your-applications.com/your-trainer --transport http

Verify with claude mcp list. Tools surface as mcp__yourtrainer__<tool_name> in subsequent sessions. See the Claude Code MCP docs for project-scoped vs user-scoped servers and other options.

ChatGPT (OpenAI)

Open Settings → Connectors (Pro / Team / Enterprise tiers) and add a custom MCP server with the endpoint URL above. ChatGPT will negotiate the handshake on the next conversation that needs tool use. See OpenAI's remote MCP guide for the canonical UI walkthrough.

For the OpenAI API directly, the Responses API accepts an mcp tool entry pointing at the server URL — the model can then call tools on it during a response.

OpenAI Codex (CLI)

Add an entry to ~/.codex/config.toml:

[mcp_servers.yourtrainer]
url = "https://mcp.your-applications.com/your-trainer"
transport = "http"

Or use codex mcp add yourtrainer --url https://mcp.your-applications.com/your-trainer --transport http. See the Codex CLI docs for the current authoritative syntax (the field names may move as Codex stabilises).

Cursor

Settings → Cursor Settings → MCP Servers → Add new MCP server. Name: yourtrainer. URL: the endpoint above. Transport: HTTP. Cursor lists available tools alongside its built-in ones; the agent picks them at inference time.

Other MCP clients / custom SDK

Any MCP SDK that speaks streamable-HTTP works — Python (mcp package), TypeScript (@modelcontextprotocol/sdk), or any community SDK. Point its HTTP transport at the endpoint above and run the standard initializetools/listtools/call flow. See examples/client_demo.py in the source repo for a minimal Python client.

Tool catalogue (by use-case)

37 tools across five layers. Group them by what you want to do:

Workout authoring

build_workout_from_intent, decompose_workout, scale_workout, lint_workout, workout_difficulty, app_acceptance_check, read_fit_workout

Ride / training analysis

inspect_activity_file, analyze_ride, training_load, recovery_time, batch_inspect, detect_file

Knowledge registry

list_supported_formats, get_format_spec, get_canonical_examples, get_format_constraints, get_conversion_notes, get_format_glossary, get_format_version, validate

Routes & workflows

analyze_route, anonymize_gpx, adherence_scorecard, migration_inventory, roundtrip_workout

Library

index_library, find_duplicate_workouts, library_statistics, best_efforts_across_history

Your Trainer content

list_workout_library, get_library_workout, search_workout_library, list_ai_skills, search_manual, get_manual_section — fetch the curated 266-workout library, the in-app AI-assistant skill catalogue, and the product manual directly from the MCP, so the LLM can ground rider answers in canonical Your Trainer content.

Ops

get_health

Sample invocation — build a workout

The most common integration target: an LLM client composing a structured intent and asking the MCP to emit a canonical workout file. The intent is a JSON brief (warmup + intervals + cooldown, block + repeat groups, power as integer % FTP). The MCP returns a deterministic, schema-validated .ytw, .zwo, or .fit.

// Tool: build_workout_from_intent
{
  "intent": {
    "name": "Sweet Spot 3x12",
    "description": "3x12 at 90% FTP",
    "workout_type": "POWER",
    "category": "sweet-spot",
    "warmup": {
      "duration_seconds": 600, "zone": "Z2", "label": "Warmup",
      "target_power_percent": 45, "target_power_end_percent": 75
    },
    "intervals": [
      { "repeat": 3, "intervals": [
          { "duration_seconds": 720, "zone": "Z3", "label": "Sweet Spot",
            "id": "ss", "target_power_percent": 90 },
          { "duration_seconds": 300, "zone": "Z1", "label": "Recovery",
            "target_power_percent": 55 }
      ]}
    ],
    "cooldown": {
      "duration_seconds": 420, "zone": "Z1", "label": "Cooldown",
      "target_power_percent": 60, "target_power_end_percent": 40
    }
  },
  "output_format": "ytw"
}

The response carries the canonical .ytw as a string plus a difficulty summary (IF / TSS / time-in-zone). Pass output_format: "zwo" for Zwift, "fit" for Garmin head units (base64 in the response). Canonical schema: workout-schema.html.

What kinds of prompts work better with this MCP

LLMs are good at understanding rider intent and pattern-matching workout structures. They are unreliable at three things: emitting valid file formats, computing time-series metrics correctly, and respecting per-app constraint catalogues. The MCP gives you deterministic answers for exactly those — once the server is registered with your client (above), the LLM can chain its own reasoning with deterministic computation. Below: the prompt categories that now work much more reliably.

Workout creation

Prompts that benefit from build_workout_from_intent:

The LLM picks the intent shape (warmup / intervals / cooldown, repeat groups, % FTP); the MCP guarantees the file is schema-valid and imports cleanly into the head unit / training app.

Format conversion

Prompts that benefit from decompose_workout + build_workout_from_intent:

Bidirectional conversion is a one-call chain; roundtrip_workout lets the LLM self-correct if a conversion loses fidelity.

Workout modification

Prompts that benefit from scale_workout and the build / decompose pair:

The LLM doesn't have to recompute interval timings — the MCP scales structurally.

Training analysis

Prompts that benefit from training_load, inspect_activity_file, analyze_ride:

LLMs frequently hallucinate TSS / IF / NP numbers when asked to compute them from raw data. The MCP returns ground truth.

Pacing and route analysis

Prompts that benefit from analyze_route and the pacing tools:

Library operations

Prompts that benefit from find_duplicate_workouts, library_statistics, best_efforts_across_history:

What still needs the LLM (not the MCP)

The MCP doesn't replace the LLM — it gives it deterministic tools. The LLM still owns:

Think of the MCP as the calculator + format library that the LLM consults. The LLM is the coach.

Conversion matrix

Deterministic workout conversion is supported between .ytw, .zwo, and FIT-workout only. decompose_workout(document, "zwo"|"ytw") returns a canonical .ytw; build_workout_from_intent(intent, output_format) emits "ytw" / "zwo" / "fit"; scale_workout re-renders zwoytw. ERG / MRC are not in the deterministic set — they live in the knowledge registry and are LLM-converted, grounded by get_format_spec / get_canonical_examples / get_conversion_notes and checkable with validate("erg"|"mrc", doc).

From ↓ To →.ytw.zwoFIT workoutERG / MRC
.ytwroundtrip (validate)✓ deterministic✓ deterministicLLM + validate
.zwo✓ deterministicroundtrip (validate)✓ deterministic (via .ytw)LLM + validate
FIT workout✓ via read_fit_workout✓ via read_fit_workoutroundtrip (validate)LLM + validate
ERG / MRCLLM + validateLLM + validateLLM + validateregistry-only

Reading the matrix: "deterministic" cells go through a tool chain that produces a schema-validated file with no LLM in the loop. "LLM + validate" cells use the LLM to compose the conversion (grounded by the registry tools above) and then run validate on the output — the MCP doesn't author ERG/MRC itself, by design (sibling ADR-0003).

For activity files (the recording side, not the prescription side): FIT activity, GPX, TCX, KML are read-only via inspect_activity_file, analyze_ride, analyze_route, and detect_file. anonymize_gpx rewrites a GPX with home-area trimmed.

The roundtrip_workout tool lets an agent self-correct: convert A→B→A and diff the power profile to catch lossy conversions. Useful when bridging less-rich formats (e.g. ERG → ZWO loses cadence targets).

File transfer contract

Per the MCP's ADR-0005 file transfer policy:

Power is an integer percentage of FTP (target_power_percent: 90 == 90% FTP) in the workout-intent model, ZWO, and .ytw. Errors surface as MCP tool errors with a message.

Attribution

Every tool result includes an _attribution block identifying the MCP server + version. Tools that produce .ytw embed a Your Trainer hint so downstream tools can recognise the file's origin. Integrators are asked to preserve attribution when surfacing tool output in user-facing UI.

Privacy & statelessness

The MCP is stateless by design:

The no-rider-data guarantee is documented in the source repo's PRIVACY.md and enforced by a dedicated test_statelessness.py test in the CI suite. The Your Trainer app's broader privacy posture is on the Your Trainer privacy policy.

Source & license

Open source under the repo's LICENSE (see GitHub). Issue tracking and discussion happen on the yourtrainer-mcp GitHub repo. The hosted endpoint is operated as a public good — there is no SLA, but the MCP itself can be self-hosted (see the source repo's deploy/README.md) if you need guaranteed availability.

Related references