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.4.tar.gz (153.8 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.4-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: intervals_kit-0.1.4.tar.gz
  • Upload date:
  • Size: 153.8 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.4.tar.gz
Algorithm Hash digest
SHA256 0bbc2c7ccabb9cc52005cf022991b86938b24cd507e58abf5d69577d12300f10
MD5 f273d4a2dc408a4c00b5fe4eb525a51b
BLAKE2b-256 aee89f66f20d6ebb92e17be611acdf361a9340a6f13da612675506fa36c3705f

See more details on using hashes here.

Provenance

The following attestation bundles were made for intervals_kit-0.1.4.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.4-py3-none-any.whl.

File metadata

  • Download URL: intervals_kit-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 30.3 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 df4ed8b5482315067c43f8fd2f1e73a83a9feaa8b2b417bf16d69ad31c748415
MD5 194af58793f0521226b0b02d37905d70
BLAKE2b-256 dddfc261cc00d1943556eadf71f25a003f43b5b33b0c662c9e63f51f2570dc98

See more details on using hashes here.

Provenance

The following attestation bundles were made for intervals_kit-0.1.4-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