Skip to main content
Glama
VSidhArt

Intervals.icu MCP Server

by VSidhArt

Intervals.icu MCP Server

A Model Context Protocol (MCP) server that enables AI assistants to interact with intervals.icu fitness tracking data.

Features

  • Fetch activities data with date filtering

  • Retrieve wellness metrics with date filtering

  • Clean data output (removes empty/null values)

  • Basic authentication with intervals.icu API

Related MCP server: Intervals.icu MCP Server

Requirements

  • Python 3.12+

  • UV package manager

  • Intervals.icu API key

  • Your intervals.icu athlete ID

Installation

1. Install UV (if not already installed)

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

2. Clone and Setup Project

git clone <repository-url>
cd intervals-mcp
uv sync

3. Get Your Intervals.icu Credentials

  1. Go to intervals.icu/settings

  2. Scroll down to "Developer Settings"

  3. Generate an API key

  4. Note your athlete ID (e.g., i335136 from your profile URL)

4. Configure Claude Desktop

Add the following to your Claude Desktop configuration file:

Location: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

{
  "mcpServers": {
    "intervals-icu": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/intervals-mcp",
        "run",
        "main.py"
      ],
      "env": {
        "INTERVALS_API_KEY": "your-api-key-here",
        "INTERVALS_ATHLETE_ID": "your-athlete-id"
      }
    }
  }
}

Replace:

  • /path/to/intervals-mcp with the absolute path to this repository

  • your-api-key-here with your intervals.icu API key

  • your-athlete-id with your athlete ID (e.g., i335136)

5. Restart Claude Desktop

Restart Claude Desktop to load the new MCP server.

Usage

Once configured, you can use these tools in Claude Desktop:

Get Activities

Get my activities from 2025-07-28
Get my activities grouped by sport from 2025-07-01 to 2025-07-28
Show my weekly activity summary for July 2025

Get Wellness Data

Show my wellness data from 2025-07-01 to 2025-07-28
Show my weekly wellness summary for July 2025
Get my monthly wellness trends grouped by week

Available Tools

get_activities(oldest_date, newest_date=None)

Fetches detailed activities from intervals.icu. Use for small datasets or when you need full activity details.

Parameters:

  • oldest_date (required): Start date in YYYY-MM-DD format

  • newest_date (optional): End date in YYYY-MM-DD format

get_grouped_activities(oldest_date, newest_date=None, group_by="sport", include_details=False)

Fetches and groups activities to reduce data volume. Recommended for analyzing multiple activities or time periods.

Parameters:

  • oldest_date (required): Start date in YYYY-MM-DD format

  • newest_date (optional): End date in YYYY-MM-DD format

  • group_by (optional): Grouping method - "sport", "day", "week", or "month" (default: "sport")

  • include_details (optional): Include filtered activity details in each group (default: false)

Returns grouped statistics: activity counts, total time/distance/calories, averages per group, and overall totals.

get_wellness(oldest_date, newest_date=None)

Fetches wellness metrics from intervals.icu.

Parameters:

  • oldest_date (required): Start date in YYYY-MM-DD format

  • newest_date (optional): End date in YYYY-MM-DD format

Development

Testing the Server

# Test imports and basic structure
INTERVALS_API_KEY=test_key INTERVALS_ATHLETE_ID=i335136 uv run python -c "import tools.activities; import tools.wellness; print('OK')"

# Run the server locally
INTERVALS_API_KEY=your_key INTERVALS_ATHLETE_ID=your_id uv run main.py

Project Structure

intervals-mcp/
├── pyproject.toml          # UV project configuration
├── main.py                 # Entry point
├── server.py               # FastMCP server instance
├── tools/
│   ├── activities.py       # Activities data tool
│   └── wellness.py         # Wellness data tool
└── utils/
    └── intervals_client.py # HTTP client with authentication

API Documentation

For more information about the intervals.icu API, visit:

License

This project is open source and available under the MIT License.

Available Tools

4 tools
get_activitiesA

Primary tool for fetching activities from intervals.icu for the configured athlete.

Best for: Getting complete list of activities within a date range, analyzing training history, exporting activity data. Not recommended for: Large date ranges without pagination; real-time activity tracking. Common mistakes: Using wrong date format (must be YYYY-MM-DD); requesting too large date ranges that may timeout. Prompt Example: "Get my activities from 2024-01-01 to 2024-01-31" or "Show me all activities from last week" Usage Example:

{
  "name": "get_activities",
  "arguments": {
    "oldest_date": "2024-01-01",
    "newest_date": "2024-01-31"
  }
}

Tool Relationships: Use this first to get activity list, then use get_grouped_activities for aggregated analysis, or get specific activity details as needed. Returns: Complete activity data including id, name, type, distance, duration, power, heart rate, and other metrics.

Parameters

oldest_date : str The oldest date to fetch activities from (format: YYYY-MM-DD). This parameter is required. newest_date : str, optional The newest date to fetch activities from (format: YYYY-MM-DD). If not provided, no upper date limit is applied.

Returns

dict Dictionary containing: - status: "success" or "error" - count: Number of activities returned - activities: List of transformed activity objects

Raises

ValidationError: If date format is invalid. IntervalsError: If the API request fails.

ParametersJSON Schema
NameRequiredDescriptionDefault
oldest_dateYes
newest_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it's a read operation (implied by 'fetching'), warns about potential timeouts with large date ranges, specifies date format requirements, and outlines error conditions (ValidationError, IntervalsError). However, it doesn't explicitly mention rate limits, authentication needs, or pagination details, leaving some gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Best for, Not recommended for, Common mistakes, Prompt Example, Usage Example, Tool Relationships, Returns, Parameters, Raises), making it easy to scan. While comprehensive, it's slightly verbose with some redundancy (e.g., date format repeated multiple times), but every section adds value, so it's appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 2 parameters with 0% schema coverage, no annotations, but has an output schema, the description provides excellent contextual completeness. It fully documents parameters, usage guidelines, behavioral traits (timeouts, errors), relationships with sibling tools, and includes examples. The output schema handles return values, so the description's Returns section is sufficient without needing to detail every field.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, so the description must fully compensate. It does so excellently: it clearly documents both parameters (oldest_date, newest_date), specifies required vs. optional status, explains format (YYYY-MM-DD), describes default behavior (no upper limit if newest_date not provided), and includes prompt and usage examples that illustrate parameter usage. This adds substantial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool's purpose as 'fetching activities from intervals.icu for the configured athlete' and distinguishes it from siblings by noting it's the 'Primary tool' for getting a 'complete list of activities within a date range'. It clearly specifies the verb (fetching/getting), resource (activities), and scope (date range, configured athlete).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance with dedicated sections: 'Best for:' lists specific use cases (complete list, analyzing training history, exporting), 'Not recommended for:' warns against large date ranges without pagination and real-time tracking, and 'Tool Relationships:' directs to sibling tools (get_grouped_activities for aggregated analysis, get specific details as needed). This covers when to use, when not to use, and alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_grouped_activitiesA

Tool for fetching and grouping activities to reduce data volume and show patterns.

Best for: Analyzing training patterns, summarizing activity by sport/time period, creating training reports, reducing data volume for large date ranges. Not recommended for: Getting individual activity details; real-time tracking. Common mistakes: Using invalid group_by value; requesting details for large datasets. Prompt Example: "Group my activities by sport from January" or "Show me weekly activity summary for last month" Usage Example:

{
  "name": "get_grouped_activities",
  "arguments": {
    "oldest_date": "2024-01-01",
    "newest_date": "2024-01-31",
    "group_by": "week",
    "include_details": false
  }
}

Tool Relationships: Use after get_activities to analyze patterns, or directly for summarized data when individual activities aren't needed. Returns: Grouped activity data with summaries (count, duration, distance) per group.

Parameters

oldest_date : str The oldest date to fetch activities from (format: YYYY-MM-DD). This parameter is required. newest_date : str, optional The newest date to fetch activities from (format: YYYY-MM-DD). If not provided, no upper date limit is applied. group_by : str, optional How to group activities. Options: "sport", "day", "week", "month". Default: "sport" include_details : bool, optional Whether to include filtered activity details in each group. Default: False

Returns

dict Dictionary containing: - groups: Dictionary of groups with summaries - total_activities: Total number of activities - Additional metadata based on grouping type

Raises

ValidationError: If parameters are invalid. IntervalsError: If the API request fails.

ParametersJSON Schema
NameRequiredDescriptionDefault
oldest_dateYes
newest_dateNo
group_byNosport
include_detailsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes the tool's purpose, common mistakes (e.g., invalid group_by values), and return structure, though it lacks details on rate limits, authentication needs, or error handling beyond the 'Raises' section. It adds significant value beyond the input schema without contradicting any annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Best for, Not recommended, Parameters, Returns, etc.), but it includes redundant elements like the JSON usage example and prompt examples that could be condensed. Most sentences earn their place by providing useful information, though some formatting adds bulk without proportional value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 parameters, 0% schema coverage, no annotations, but an output schema, the description is highly complete. It covers purpose, usage guidelines, parameters, returns, errors, and relationships with sibling tools, providing all necessary context for an agent to understand and invoke the tool correctly without relying on structured fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Given 0% schema description coverage, the description compensates fully by detailing all parameters in the 'Parameters' section, including their purposes, formats, defaults, and optionality. It explains 'oldest_date' as the oldest date to fetch from, 'newest_date' as an optional upper limit, 'group_by' options, and 'include_details' effect, adding crucial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool 'fetches and groups activities to reduce data volume and show patterns,' which is a specific verb+resource combination. It distinguishes from sibling tools like 'get_activities' by emphasizing grouping and summarization rather than individual activity retrieval, making the purpose unambiguous and differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance with 'Best for' and 'Not recommended for' sections, clearly outlining when to use this tool versus alternatives. It mentions using it after 'get_activities' for analysis or directly for summarized data, and warns against using it for individual details or real-time tracking, offering comprehensive usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_grouped_wellnessA

Tool for fetching and grouping wellness data to show trends and patterns.

Best for: Analyzing wellness trends over time, creating health reports, tracking recovery patterns, monitoring training stress balance, identifying correlations. Not recommended for: Individual day analysis; real-time monitoring. Common mistakes: Using invalid group_by value; requesting details for very large datasets. Prompt Example: "Show me monthly wellness trends for 2024" or "Group my wellness data by week for the last 3 months" Usage Example:

{
  "name": "get_grouped_wellness",
  "arguments": {
    "oldest_date": "2024-01-01",
    "newest_date": "2024-03-31",
    "group_by": "month",
    "include_details": false
  }
}

Tool Relationships: Use after get_wellness to analyze patterns, or directly for trend analysis when individual records aren't needed. Returns: Grouped wellness data with averages and statistics per time period.

Parameters

oldest_date : str The oldest date to fetch wellness data from (format: YYYY-MM-DD). This parameter is required. newest_date : str, optional The newest date to fetch wellness data from (format: YYYY-MM-DD). If not provided, no upper date limit is applied. group_by : str, optional How to group wellness data. Options: "week", "month", "all". Default: "month" include_details : bool, optional Whether to include individual records in each group. Default: False

Returns

dict Dictionary containing: - status: "success" or "error" - groups: Dictionary of groups with summaries (when not "all") - summary: Aggregate statistics (when group_by is "all") - total_records: Total number of wellness records - Additional metadata based on grouping type

Raises

ValidationError: If parameters are invalid. IntervalsError: If the API request fails.

ParametersJSON Schema
NameRequiredDescriptionDefault
oldest_dateYes
newest_dateNo
group_byNomonth
include_detailsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes the tool's behavior: it groups data over time periods, returns averages and statistics, and includes warnings about common mistakes (e.g., invalid group_by values). However, it lacks details on error handling beyond the 'Raises' section, such as rate limits or authentication needs, which could be more explicit for a tool with no annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (e.g., 'Best for:', 'Parameters', 'Returns'), but it is somewhat lengthy due to including examples and detailed parameter info. Every sentence adds value, such as usage examples and tool relationships, but it could be more front-loaded by emphasizing key points earlier to improve efficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of the tool (4 parameters, no annotations, schema coverage 0%), the description is highly complete. It covers purpose, usage guidelines, parameters, returns (with an output schema provided), and error handling. The presence of an output schema reduces the need to explain return values in detail, and the description supplements this adequately with examples and contextual info.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, so the description must compensate fully. It does so by providing detailed parameter semantics in the 'Parameters' section, including data types, formats (e.g., YYYY-MM-DD), optionality, default values, and allowed options for 'group_by' (e.g., 'week', 'month', 'all'). This adds significant meaning beyond the basic input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'fetching and grouping wellness data to show trends and patterns.' It uses specific verbs ('fetching,' 'grouping') and distinguishes from sibling tools by mentioning 'get_wellness' for individual records versus this tool for trend analysis. The title is null, so the description fully carries this burden.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance with 'Best for:' and 'Not recommended for:' sections, clearly stating when to use this tool (e.g., analyzing trends over time) versus alternatives (e.g., individual day analysis). It also includes 'Tool Relationships' that references sibling tools like 'get_wellness' for context on when to use this tool directly or after others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_wellnessA

Primary tool for fetching wellness data from intervals.icu for the configured athlete.

Best for: Getting daily wellness metrics, tracking health trends, monitoring recovery, analyzing sleep patterns, weight tracking. Not recommended for: Real-time monitoring; medical diagnosis; very large date ranges. Common mistakes: Using wrong date format (must be YYYY-MM-DD); requesting years of data at once. Prompt Example: "Get my wellness data from 2024-01-01 to 2024-01-31" or "Show me wellness metrics for last month" Usage Example:

{
  "name": "get_wellness",
  "arguments": {
    "oldest_date": "2024-01-01",
    "newest_date": "2024-01-31"
  }
}

Tool Relationships: Use this first to get wellness records, then use get_grouped_wellness for trend analysis or summary statistics. Returns: Complete wellness data including weight, HRV, resting HR, sleep, fatigue, mood, motivation, and training metrics (ATL/CTL/TSB).

Parameters

oldest_date : str The oldest date to fetch wellness data from (format: YYYY-MM-DD). This parameter is required. newest_date : str, optional The newest date to fetch wellness data from (format: YYYY-MM-DD). If not provided, no upper date limit is applied.

Returns

dict Dictionary containing: - status: "success" or "error" - count: Number of wellness records returned - wellness: List of transformed wellness objects - date_range: Date range of the wellness data

Raises

ValidationError: If date format is invalid. IntervalsError: If the API request fails.

ParametersJSON Schema
NameRequiredDescriptionDefault
oldest_dateYes
newest_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it's a read operation (implied by 'fetching'), includes constraints (date format requirements, warnings about large date ranges), error handling (raises ValidationError and IntervalsError), and return structure. It doesn't mention rate limits or authentication needs, but covers most critical aspects for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Best for, Not recommended, etc.), but it's verbose with redundant elements. The 'Prompt Example' and 'Usage Example' are somewhat repetitive, and the 'Parameters' and 'Returns' sections duplicate information that could be inferred from the schema. It's front-loaded with key info but includes unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (2 parameters, no annotations, but with output schema), the description is highly complete. It covers purpose, usage guidelines, behavioral traits, parameter semantics, error handling, and relationships with sibling tools. The output schema exists, so the description appropriately explains return values without over-documenting them. No significant gaps remain for effective tool use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It fully documents both parameters: oldest_date (required, YYYY-MM-DD format) and newest_date (optional, same format, with default behavior if not provided). The description adds essential meaning beyond the bare schema, including format requirements and behavioral details like 'no upper date limit' for missing newest_date.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches wellness data from intervals.icu for a configured athlete, specifying the resource (wellness data) and source (intervals.icu). It distinguishes from sibling tools by mentioning get_grouped_wellness for trend analysis, though it doesn't explicitly differentiate from get_activities or get_grouped_activities. The purpose is specific but not fully sibling-differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance with 'Best for' and 'Not recommended for' sections, detailing use cases (daily wellness metrics, health trends) and exclusions (real-time monitoring, medical diagnosis). It also names an alternative tool (get_grouped_wellness) for trend analysis, offering clear when-to-use and when-not-to-use advice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: get_activities retrieves individual activity records, get_grouped_activities provides aggregated activity summaries, get_wellness fetches individual wellness metrics, and get_grouped_wellness offers aggregated wellness trends. The descriptions explicitly differentiate between individual data retrieval and grouped analysis for both domains.

Naming Consistency5/5

All tools follow a perfectly consistent verb_noun pattern with clear prefixes: get_activities, get_grouped_activities, get_wellness, get_grouped_wellness. The naming convention is uniform throughout, using snake_case consistently and maintaining parallel structure between activity and wellness domains.

Tool Count4/5

Four tools is reasonable for a fitness/wellness data server, covering the core domains of activities and wellness with both individual and grouped variants. However, the count feels slightly minimal - there might be room for additional operations like creating or updating records, though the current set adequately serves basic retrieval and analysis needs.

Completeness3/5

The toolset provides excellent read/analysis coverage for activities and wellness data, but lacks any write operations (create, update, delete). For a fitness tracking platform where users might want to log new activities or update wellness metrics, this represents a notable gap. The surface is complete for retrieval and analysis but incomplete for full CRUD lifecycle management.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VSidhArt/intervals-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server