Skip to main content

MCP server, CLI, and Python library for the Intervals.ICU fitness tracking API

Project description

intervals-kit

MCP server, CLI, and Python library for the Intervals.ICU fitness tracking API. Exposes activity data (power curves, HR curves, streams, intervals, segments, file downloads) to AI assistants via the Model Context Protocol, and as a command-line tool for scripting and bulk data access.

Requirements

  • Python 3.10+
  • uv — recommended for running the package

Installation

pip install intervals-kit

Or with uv:

uv pip install intervals-kit

Configuration

The package reads credentials from environment variables or a config file.

Environment variables (recommended):

export INTERVALS_API_KEY=your_api_key      # From intervals.icu → Settings → API Key
export INTERVALS_ATHLETE_ID=iXXXXXX       # Your athlete ID (visible in the URL when logged in)

Config file (~/.config/intervals-kit/config.toml):

api_key = "your_api_key"
athlete_id = "iXXXXXX"
base_url = "https://intervals.icu"   # optional

Environment variables take precedence over the config file.

Usage as MCP Server (Claude Code / Claude Desktop)

The easiest way — no installation needed:

{
  "mcpServers": {
    "intervals-icu": {
      "command": "uvx",
      "args": ["intervals-kit"],
      "env": {
        "INTERVALS_API_KEY": "your_api_key",
        "INTERVALS_ATHLETE_ID": "iXXXXXX"
      }
    }
  }
}

Once configured, Claude can directly query your training data:

"How many rides did I do last month?" "What was my best 5-minute power in March?" "Download my activities as a CSV for Q1 2025."

Available MCP Tools

Tool Description
list_activities List activities for a date range
get_activity Get full details for a single activity
search_activities Search by name or tag
update_activity Update name, description, type, or RPE
get_activity_intervals Get lap/split data
get_activity_streams Get second-by-second time-series (power, HR, cadence, …)
get_power_curve Mean-maximal power curve for an activity
get_hr_curve Heart rate curve for an activity
get_pace_curve Pace curve for running/swimming
get_best_efforts Best efforts detected in an activity
get_activity_segments Matched Strava/Intervals segments
get_activity_map GPS track (lat/lon)
get_athlete_power_curves Best power curves across a date range
get_athlete_hr_curves Best HR curves across a date range

For large data (streams >1 hour, CSV exports, binary files) the MCP tools return metadata and tell Claude to use the CLI for the actual download.

Usage as CLI

uvx --from intervals-kit intervals-icu-tools --help

Activity commands

# List activities for a date range (JSON to stdout)
uvx --from intervals-kit intervals-icu-tools list-activities --oldest 2025-01-01 --newest 2025-03-31

# Save to a file instead of stdout
uvx --from intervals-kit intervals-icu-tools -o ./data list-activities --oldest 2025-01-01 --newest 2025-03-31

# Get a single activity
uvx --from intervals-kit intervals-icu-tools get-activity i136292802

# Search by name or tag (# prefix for exact tag match)
uvx --from intervals-kit intervals-icu-tools search-activities "long ride"
uvx --from intervals-kit intervals-icu-tools search-activities "#race" --full

# Update fields
uvx --from intervals-kit intervals-icu-tools update-activity i136292802 --perceived-exertion 7 --description "Felt strong"

Sub-resource commands

# Lap/interval data
uvx --from intervals-kit intervals-icu-tools get-intervals i136292802

# Time-series streams (specify types to limit size)
uvx --from intervals-kit intervals-icu-tools -o ./data get-streams i136292802 --types watts,heartrate,cadence

# Power / HR / pace curves
uvx --from intervals-kit intervals-icu-tools get-power-curve i136292802
uvx --from intervals-kit intervals-icu-tools get-hr-curve i136292802
uvx --from intervals-kit intervals-icu-tools get-pace-curve i136292816  # running activity

# Best efforts, segments, GPS map
uvx --from intervals-kit intervals-icu-tools get-best-efforts i136292802
uvx --from intervals-kit intervals-icu-tools get-segments i136292802
uvx --from intervals-kit intervals-icu-tools -o ./data get-activity-map i136292802

File download commands

# Download original upload / FIT / GPX file
uvx --from intervals-kit intervals-icu-tools -o ./data download-activity-file i136292802 --type fit
uvx --from intervals-kit intervals-icu-tools -o ./data download-activity-file i136292802 --type gpx

# Bulk CSV export for a date range
uvx --from intervals-kit intervals-icu-tools -o ./data download-activities-csv --oldest 2025-01-01 --newest 2025-03-31

Aggregate curves

# Best power/HR/pace curves across all activities in a date range
uvx --from intervals-kit intervals-icu-tools get-athlete-power-curves --oldest 2025-01-01 --newest 2025-03-31
uvx --from intervals-kit intervals-icu-tools get-athlete-hr-curves --oldest 2025-01-01 --newest 2025-03-31
uvx --from intervals-kit intervals-icu-tools get-athlete-pace-curves --oldest 2025-01-01 --newest 2025-03-31

Global options

Option Default Description
-o / --output-dir . (stdout) Directory to save output files
-f / --format json Output format: json or csv

Exit codes

Code Meaning
0 Success
1 Auth error or general API error
2 Rate limit exceeded (retryable)
3 Download / network error (retryable)
4 Resource not found

Usage as Python Library

import asyncio
from intervals_kit import IntervalsService, load_config

async def main():
    svc = IntervalsService(load_config())

    # List March 2025 activities
    activities = await svc.list_activities("2025-03-01", "2025-03-31")
    rides = [a for a in activities if a.type == "Ride"]
    print(f"Rides: {len(rides)}, Runs: {len(activities) - len(rides)}")

    # Get power curve for first ride
    if rides:
        curve = await svc.get_power_curve(rides[0].id)
        print(f"Power curve keys: {list(curve.keys())}")

asyncio.run(main())

Development

# Clone and install with dev dependencies
git clone https://github.com/jrsassen/intervals-kit
cd intervals-kit
uv sync

# Run tests
uv run pytest

# Run a single test
uv run pytest tests/test_service.py -k test_name

# Run integration tests against the real API (requires credentials)
uv run pytest -m integration

Architecture

Three interfaces share one service layer — see docs/SPECIFICATIONS.md for the full architecture and src/intervals_kit/cli_tools.md for the complete CLI reference intended for LLM agents.

MCP Tools (FastMCP)  ──┐
CLI Commands (Click)  ──┼──▶  service.py  ──▶  client.py  ──▶  Intervals.ICU API
Python import        ──┘

Source layout:

src/intervals_kit/
├── errors.py        # Exception types
├── models.py        # Pydantic models
├── config.py        # Configuration loading
├── client.py        # HTTP client (auth, error mapping, streaming)
├── exporters.py     # JSON serialization
├── service.py       # All business logic
├── mcp_server.py    # FastMCP tool definitions
└── cli/             # Click command definitions

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

intervals_kit-0.1.3.tar.gz (153.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

intervals_kit-0.1.3-py3-none-any.whl (30.1 kB view details)

Uploaded Python 3

File details

Details for the file intervals_kit-0.1.3.tar.gz.

File metadata

  • Download URL: intervals_kit-0.1.3.tar.gz
  • Upload date:
  • Size: 153.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for intervals_kit-0.1.3.tar.gz
Algorithm Hash digest
SHA256 26d1d2f45cc10ca313d53b59385debb6c4b72c571f5f0d7b9a19967b95394967
MD5 b74df19d0921078278f57ea7300f2643
BLAKE2b-256 d0f82ee741e51a1e815ead592c1d78d5aac9e6c8b90456407f909994c2dc2fc9

See more details on using hashes here.

Provenance

The following attestation bundles were made for intervals_kit-0.1.3.tar.gz:

Publisher: publish.yml on jrsassen/intervals-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file intervals_kit-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: intervals_kit-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 30.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for intervals_kit-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8e5793a6fd98b4efd7fc1b6f99af44770361edd1cc3b7be186addace4a924940
MD5 e61f0db6c565ae593458af99ea9649b7
BLAKE2b-256 cbbf30a4889fd385fac885e13b0a00b5c34187727ced92ed0ca8b258251d68ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for intervals_kit-0.1.3-py3-none-any.whl:

Publisher: publish.yml on jrsassen/intervals-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page