Skip to main content
Glama
banananovej-chuan

TrainingPeaks MCP Server

README.md
# TrainingPeaks MCP Server

[![PyPI](https://img.shields.io/pypi/v/tp-mcp-server)](https://pypi.org/project/tp-mcp-server/)
[![Python 3.12+](https://img.shields.io/pypi/pyversions/tp-mcp-server)](https://pypi.org/project/tp-mcp-server/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

A [Model Context Protocol](https://modelcontextprotocol.io/) server for TrainingPeaks with an analytics focus — enabling real-time querying of training data, performance trends, CTL/ATL/TSB analysis, and training load optimization through Claude Desktop.

```bash
# Install and run — no cloning needed
uvx tp-mcp-server
```

## Features

**14 tools** organized across 5 categories:

| Category | Tools | Description |
|----------|-------|-------------|
| Auth | `tp_auth_status`, `tp_refresh_auth` | Check/refresh authentication |
| Profile | `tp_get_profile` | Athlete profile + auto-detect ID |
| Workouts | `tp_get_workouts`, `tp_get_workout` | List and detail past workouts |
| | `tp_get_planned_workouts` | Upcoming planned workouts with coach instructions |
| Fitness | `tp_get_fitness` | CTL/ATL/TSB with computed values |
| Peaks | `tp_get_peaks`, `tp_get_workout_prs` | Personal records by sport |
| Analytics | `tp_training_load_summary` | Weekly/monthly TSS, load ramp rate |
| | `tp_fitness_trend` | CTL trajectory, 7-day projection |
| | `tp_workout_analysis` | Efficiency factor, variability index |
| | `tp_performance_summary` | Sport-specific volume & consistency |
| | `tp_training_zones_distribution` | IF-based zone breakdown |

**Key feature**: CTL/ATL/TSB are computed from TSS using standard exponential weighted moving averages (42-day/7-day time constants), since the TP API doesn't return these values directly.

## Quick Start (recommended)

The fastest way to get running — no cloning or venv needed.

### 1. Install uv (if you don't have it)

[uv](https://docs.astral.sh/uv/) is a fast Python package manager built by [Astral](https://astral.sh/) (the company behind [Ruff](https://docs.astral.sh/ruff/)). It includes `uvx`, a tool that can download and run Python packages in isolated environments — no manual setup needed. It's open-source, widely adopted in the Python community, and used by projects like FastAPI, Pydantic, and many MCP servers.

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

### 2. Get your TrainingPeaks auth cookie

1. Open your browser and go to [trainingpeaks.com](https://trainingpeaks.com) and log in
2. Open **Developer Tools** (`Cmd+Option+I` on Mac, `F12` on Windows/Linux)
3. Click the **Application** tab (Chrome/Edge) or **Storage** tab (Firefox)
4. In the left sidebar, expand **Cookies** and click on `https://www.trainingpeaks.com`
5. Find the cookie named **`Production_tpAuth`**
6. Double-click its **Value** column and copy the entire string

### 3. Add to Claude Desktop

Open your Claude Desktop config file:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

> **Note**: If this file doesn't exist yet (first time configuring an MCP server), create it yourself. On macOS, the `Claude` folder inside `Application Support` should already exist if you've opened Claude Desktop at least once — you just need to create the `claude_desktop_config.json` file inside it.

First, find the full path to `uvx`:

```bash
which uvx
```

This will output something like `/Users/yourname/.local/bin/uvx`.

Then add this to your config (replace the `command` path and `your_cookie_value`):

```json
{
  "mcpServers": {
    "trainingpeaks": {
      "command": "/Users/yourname/.local/bin/uvx",
      "args": ["tp-mcp-server"],
      "env": {
        "TP_AUTH_COOKIE": "your_cookie_value"
      }
    }
  }
}
```

> **Important**: You must use the **full absolute path** to `uvx` (not just `"uvx"`). Claude Desktop has a limited PATH and won't find it otherwise.

### 4. Restart Claude Desktop

Fully quit and reopen Claude Desktop. You should see "trainingpeaks" listed as a connected MCP server (look for the hammer icon).

That's it — no cloning, no virtual environments. `uvx` automatically downloads and runs the package from [PyPI](https://pypi.org/project/tp-mcp-server/).

---

## Alternative: Install from source

If you want to modify the code or contribute:

### Prerequisites

- **Python 3.12+**
- **[uv](https://docs.astral.sh/uv/)** (recommended) or pip

### Steps

```bash
git clone https://github.com/banananovej-chuan/tp-mcp-server.git
cd tp-mcp-server
uv venv --python 3.12
uv pip install .
```

Get your cookie (see step 2 above), then configure the environment:

```bash
cp .env.example .env
# Edit .env and paste your cookie value
```

For Claude Desktop, use the absolute path to the venv Python:

```json
{
  "mcpServers": {
    "trainingpeaks": {
      "command": "/absolute/path/to/tp-mcp-server/.venv/bin/python",
      "args": ["-m", "tp_mcp_server"],
      "env": {
        "TP_AUTH_COOKIE": "your_cookie_value"
      }
    }
  }
}
```

> **Important**: The `command` path must be an **absolute path**. On macOS/Linux it starts with `/`, on Windows use the full path like `C:\\Users\\yourname\\tp-mcp-server\\.venv\\Scripts\\python.exe`. Do not use `~` or relative paths.

## Example Queries

Once connected in Claude Desktop, try:

- "What's my current fitness level?"
- "Show my planned workouts for the next 2 weeks"
- "Show my training load trend for the last 3 months"
- "Analyze my last bike workout"
- "What are my power PRs?"
- "How is my training zone distribution this month?"
- "Compare my bike performance over the last 90 days"

## Refreshing Your Auth Cookie

The TrainingPeaks auth cookie expires periodically (typically every few days to weeks). When it expires:

1. You'll see authentication errors in Claude Desktop
2. Re-extract the cookie from your browser (repeat Step 2 from Quick Start)
3. Update the `TP_AUTH_COOKIE` value in your Claude Desktop config (and `.env` file if using source install)
4. Restart Claude Desktop

## Architecture

```
src/tp_mcp_server/
├── server.py              # FastMCP entry point
├── mcp_instance.py        # Shared MCP instance
├── config.py              # Environment config
├── api/
│   ├── client.py          # Async httpx client, token management
│   └── endpoints.py       # API URL constants
├── auth/
│   ├── storage.py         # Cookie storage (env/keyring)
│   └── browser.py         # Browser cookie extraction
├── tools/
│   ├── auth.py            # Auth status/refresh
│   ├── profile.py         # Athlete profile
│   ├── workouts.py        # Workout list/detail
│   ├── fitness.py         # CTL/ATL/TSB data
│   ├── peaks.py           # Personal records
│   └── analytics.py       # Derived analytics
├── models/
│   ├── workout.py         # Workout models
│   ├── fitness.py         # Fitness models + CTL computation
│   ├── peaks.py           # PR models
│   └── profile.py         # Profile model
└── utils/
    ├── dates.py            # Date helpers
    └── formatting.py       # Output formatting
```

## Known Limitations

- **Internal API**: TrainingPeaks has no public API. This uses the same internal API as the web app, which could change without notice.
- **Cookie auth**: Requires periodic browser re-login to refresh the cookie.
- **Sport-level PRs**: The `/personalrecord/v2/athletes/{id}/{sport}` endpoint returns 500. PRs are aggregated from individual workouts instead.
- **CTL/ATL/TSB**: The API returns `"NaN"` for these values. They are computed locally from TSS data.
- **Rate limiting**: Requests are throttled to 150ms apart to avoid hitting TP rate limits.

TDQS

A4/5.0

Scored across 14 tools

Disambiguation5/5

Each tool serves a distinct purpose without overlap. For example, tp_get_fitness returns daily CTL/ATL/TSB, tp_fitness_trend projects future values, and tp_training_load_summary provides weekly/monthly TSS totals. Similarly, tp_get_workout gives raw data while tp_workout_analysis computes derived metrics. Auth tools are separate, and each analytics tool focuses on a unique aspect.

Naming Consistency4/5

All tools follow a tp_ prefix with snake_case naming. The verb usage is mostly consistent, with many using 'get_' (e.g., tp_get_fitness, tp_get_workouts) and others using descriptive verbs like 'fitness_trend' or 'performance_summary'. Some names like tp_auth_status or tp_training_zones_distribution are nouns rather than verbs, but overall the pattern is predictable.

Tool Count5/5

14 tools cover a broad yet focused range of fitness data operations including authentication, profile, workouts (planned and completed), fitness metrics, trends, peaks/PRs, and detailed analysis. Each tool earns its place without redundancy or excessive specialization.

Completeness5/5

The tool set provides comprehensive coverage for a read-only analytics server. It includes auth, profile, workout retrieval (planned and historical), fitness metrics, trends, peaks/PRs, workout analysis, training load summary, and zones distribution. No obvious gaps for the domain.

Maintenance

ActivityInactive
ResponsivenessNo issues