npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

trainingpeaks-mcp

v0.14.7

Published

MCP server for programmatic access to your TrainingPeaks data

Downloads

187

Readme

trainingpeaks-mcp

An MCP (Model Context Protocol) server for accessing your TrainingPeaks training data. Works with Claude Desktop, ChatGPT, and other MCP-compatible clients.

Features

  • 20 tools for accessing workouts, strength workouts, fitness metrics, peaks/PRs, power analysis, aerobic decoupling, workout plan compliance, ZWO workout generation, files, cache management, and date resolution
  • FIT file caching: Downloaded FIT files are cached to disk (~/.trainingpeaks-mcp/cache/fit/) — eliminates redundant downloads across sessions
  • Dual transport: stdio for Claude Desktop, HTTP for ChatGPT
  • FIT file parsing: Extract structured data from downloaded FIT files
  • Also usable as a standalone TypeScript library

Quick Start

One-Click Install (Claude Desktop)

  1. Download the latest .mcpb file from Releases
  2. Double-click the .mcpb file — Claude Desktop will open and prompt you to install
  3. Enter your TrainingPeaks credentials when prompted

That's it — no Node.js installation required. Claude Desktop bundles its own runtime.

Manual Configuration (Claude Desktop)

Requires Node.js 20+. Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "trainingpeaks": {
      "command": "npx",
      "args": ["trainingpeaks-mcp"],
      "env": {
        "TP_USERNAME": "[email protected]",
        "TP_PASSWORD": "your-password"
      }
    }
  }
}

Restart Claude Desktop. You can now ask Claude about your training data!

ChatGPT (via HTTP)

Requires Node.js 20+.

  1. Clone and install:

    git clone https://github.com/robertgregorywest/trainingpeaks-mcp.git
    cd trainingpeaks-mcp
    npm install
  2. Create .env file with your credentials:

    cp .env.example .env
    # Edit .env with your TrainingPeaks credentials
  3. Build and start the HTTP server:

    npm run build
    npm run start:http

    You should see: TrainingPeaks MCP HTTP server running on port 3000

  4. Install ngrok (if not already installed):

    macOS (Homebrew):

    brew install ngrok

    Windows (Chocolatey):

    choco install ngrok

    Or download directly from: https://ngrok.com/download

  5. Create a free ngrok account and get your auth token:

    • Sign up at https://dashboard.ngrok.com/signup
    • Copy your auth token from https://dashboard.ngrok.com/get-started/your-authtoken
    • Configure ngrok with your token:
      ngrok config add-authtoken YOUR_AUTH_TOKEN
  6. Start ngrok to expose your local server (in a new terminal):

    ngrok http 3000

    ngrok will display output like:

    Forwarding   https://abc123.ngrok-free.app -> http://localhost:3000

    Copy the https://...ngrok-free.app URL.

  7. Add the MCP connector in ChatGPT:

    • Go to ChatGPT Settings → Connectors → Add Connector
    • Enter your ngrok URL with /mcp path: https://abc123.ngrok-free.app/mcp
    • Save the connector
  8. Test by asking ChatGPT about your TrainingPeaks data!

Available Tools

| Tool | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------------------- | | get_user | Get user profile including athlete ID | | get_athlete_id | Get just the athlete ID | | get_workouts | List workouts in a date range | | get_workout | Get single workout summary | | get_workout_details | Get workout with full metrics, intervals, laps, zones | | search_workouts | Search workouts by title (case-insensitive) within a number of days | | compare_intervals | Compare laps/intervals side-by-side across workouts with power/duration filters | | get_strength_workouts | Get strength workouts in a date range (sets, blocks, exercises, compliance) | | parse_fit_file | Parse FIT file and extract structured data | | get_fitness_data | Get CTL/ATL/TSB for date range | | get_current_fitness | Get today's fitness metrics | | get_peaks | Get peaks for specific sport and type | | get_workout_peaks | Get PRs from specific workout | | get_best_power | Compute best power from raw FIT file for arbitrary durations (e.g., 3min, 8min, 45min) | | get_power_duration_curve | Build a power-duration curve across cycling workouts in a date range | | get_aerobic_decoupling | Calculate aerobic decoupling (Pw:Hr) from a workout — measures cardiac drift | | assess_compliance | Assess workout plan compliance — compares prescribed plan against actual activity with per-step and summary metrics | | build_zwo_workout | Build a Zwift .zwo workout file from structured segments (warmup, intervals, steady, ramp, cooldown, freeride) | | clear_fit_cache | Clear all cached FIT files downloaded from TrainingPeaks | | get_current_date | Get current date in ISO, US, EU, or custom format |

Example Prompts

  • "What workouts did I do last week?"
  • "Show me my current fitness (CTL, ATL, TSB)"
  • "What are my best 5-minute power efforts?"
  • "Get details for my most recent ride including heart rate zones"
  • "Download and parse the FIT file from yesterday's ride"
  • "Search for all my tempo workouts in the last 30 days"
  • "Compare the intervals across my last 3 threshold rides"
  • "What's my best 3-minute and 8-minute power from yesterday's ride?"
  • "Build my power-duration curve for the last 6 weeks"
  • "What's the aerobic decoupling for my last long ride?"
  • "How well did I follow the plan for yesterday's ride?"
  • "Create a 5x5 VO2max workout at 300W with 50% FTP recovery for Zwift"
  • "Build me a sweet spot session with 3x10min at 220W"
  • "What is today's date?"

Environment Variables

Create a .env file from the example:

cp .env.example .env

Then edit .env with your TrainingPeaks credentials:

[email protected]
TP_PASSWORD=your-password

| Variable | Description | Optional | | ------------------------- | ------------------------------------------------------------------------- | -------- | | TP_USERNAME | TrainingPeaks email address | No | | TP_PASSWORD | TrainingPeaks password | No | | PORT | HTTP server port (default: 3000) | Yes | | TP_TEST_BIKE_WORKOUT_ID | Bike workout ID with FIT file, power, and HR data (for integration tests) | Yes |

Library Usage

You can also use this package as a standalone TypeScript library:

import { createClient } from "trainingpeaks-mcp";

const client = createClient();

// Get workouts for a date range
const workouts = await client.getWorkouts("2024-01-01", "2024-12-31");

// Get workout details with metrics
const details = await client.getWorkoutDetails(workouts[0].workoutId);
console.log(details.metrics);

// Get current fitness
const fitness = await client.getCurrentFitness();
console.log(`CTL: ${fitness.ctl}, ATL: ${fitness.atl}, TSB: ${fitness.tsb}`);

// Build a power-duration curve from the last 6 weeks of rides
const curve = await client.getPowerDurationCurve({
  startDate: "2024-11-01",
  endDate: "2024-12-15",
});
console.log(curve.curve.map((p) => `${p.durationLabel}: ${p.bestPowerWatts}W`));

// Aerobic decoupling analysis
const decoupling = await client.getAerobicDecoupling(workouts[0].workoutId);
console.log(
  `Decoupling: ${decoupling.decouplingPercent}% — ${decoupling.interpretation}`,
);

// Workout plan compliance assessment
const compliance = await client.assessCompliance(workouts[0].workoutId);
console.log(
  `Plan compliance: ${compliance.overallCompliance.powerComplianceAvg}%`,
);

// Clean up when done
await client.close();

Development

npm run build        # Compile TypeScript
npm run lint         # Run ESLint
npm run test         # Run unit tests
npm run typecheck    # Type-check without emitting

Integration Tests

Integration tests make real API calls to TrainingPeaks to verify all endpoints work correctly.

Prerequisites:

  1. Create .env file with your TrainingPeaks credentials (see Environment Variables)

Run integration tests:

npm run test:integration

What's tested:

  • User API: getUser, getAthleteId
  • Workouts API: getWorkouts, getWorkout, getWorkoutDetails
  • Fitness API: getCurrentFitness, getFitnessData
  • Peaks API: getPeaks, getWorkoutPeaks
  • Files API: downloadActivityFile

Tests are skipped automatically if credentials are not available.

How It Works

This library uses Playwright to automate browser login to TrainingPeaks, capturing the authentication token from API requests. The token is then used for subsequent API calls.

License

MIT