Skip to main content
Glama
mcp-server-strava

mcp-server-strava

by rbctmz

Strava API integration with Model Context Protocol (MCP) SDK

CICodecsPythonLicense: MITRuff

Integration for training analysis and recommendations based on Strava data using the Model Context Protocol SDK.

πŸš€ Features

  • Analysis of workouts from Strava

  • Training Recommendations

  • Automatic token update

  • Rate limiting for API requests

Related MCP server: Strava MCP Server

πŸ“‹ Requirements

βš™οΈ Installation

# ΠšΠ»ΠΎΠ½ΠΈΡ€ΡƒΠ΅ΠΌ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
git clone https://github.com/rbctmz/mcp-server-strava.git
cd mcp-server-strava

# Установка Ρ‡Π΅Ρ€Π΅Π· uv (рСкомСндуСтся)
curl -LsSf https://astral.sh/uv/install.sh | sh
uv pip install .

# Установка Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
uv pip install -e ".[dev]"

Installing MCP SDK

uv add "mcp[cli]"

πŸ”§ Setting

Setting up Strava API

  1. Go to the API settings page

  2. Create an application:

    • Application Name: MCP Strava Integration

    • Category: Training Analysis

    • Website: http://localhost

    • Authorization Callback Domain: localhost

Setting up the environment

  1. Create a file with environment variables:

    cp .env-template .env
  2. Get access tokens:

    python scripts/auth.py
  3. Check the setting:

    mcp dev src/server.py
    curl -X GET "http://localhost:8000/activities"

πŸ“š API and examples

Resources and Tools

Type

Name

Description

Resource

strava://activities

List of activities

Resource

strava://activities/{id}

Activity details

Resource

strava://athlete/zones

Training zones

Resource

strava://athlete/clubs

Athlete's clubs

Resource

strava://gear/{gear_id}

Equipment Information

Tool

analyze_activity(activity_id)

Training Analysis

Tool

analyze_training_load(activities)

Load analysis

Tool

get_activity_recommendations()

Recommendations

Examples of use

from mcp import ClientSession

# ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ активностСй
async with ClientSession() as session:
    activities = await session.read_resource("strava://activities")
    activity = await session.read_resource("strava://activities/12345678")

# Анализ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΊΠΈ
result = analyze_activity(activity_id="12345678")
"""
{
    "type": "Run",
    "distance": 5000,
    "moving_time": 1800,
    "analysis": {
        "pace": 5.5,  # ΠΌΠΈΠ½/ΠΊΠΌ
        "effort": "БрСдняя"
    }
}
"""

# Анализ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
summary = analyze_training_load(activities)
"""
{
    "activities_count": 10,
    "total_distance": 50.5,  # ΠΊΠΌ
    "total_time": 5.2,      # часы
    "heart_rate_zones": {
        "easy": 4,    # Π§Π‘Π‘ < 120
        "medium": 4,  # Π§Π‘Π‘ 120-150
        "hard": 2     # Π§Π‘Π‘ > 150
    }
}
"""

# ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Π·ΠΎΠ½
async with ClientSession() as session:
    zones = await session.read_resource("strava://athlete/zones")
    """
    {
        "heart_rate": {
            "custom_zones": true,
            "zones": [
                {"min": 0, "max": 120, "name": "Z1 - Recovery"},
                {"min": 120, "max": 150, "name": "Z2 - Endurance"},
                {"min": 150, "max": 170, "name": "Z3 - Tempo"},
                {"min": 170, "max": 185, "name": "Z4 - Threshold"},
                {"min": 185, "max": -1, "name": "Z5 - Anaerobic"}
            ]
        },
        "power": {
            "zones": [
                {"min": 0, "max": 180},
                {"min": 181, "max": 250},
                {"min": 251, "max": 300},
                {"min": 301, "max": 350},
                {"min": 351, "max": -1}
            ]
        }
    }
    """

πŸ›  Development

CI/CD and Security

  • Coverage

  • Tests

  • Ruff

Checks in GitHub Actions

Type

Tool

Description

Linting

ruff

Code formatting and analysis

Tests

pytest

Unit and integration tests

Coating

pytest-cov

Code Coverage Report

Security and Secrets

  1. Token protection:

    • .env to .gitignore

    • GitHub Secrets for CI/CD

    • Rate limiting: 100 requests/15 min

  2. Setting up secrets:

    # Π’ GitHub: Settings β†’ Secrets β†’ Actions
    STRAVA_CLIENT_ID=<client_id>
    STRAVA_CLIENT_SECRET=<client_secret>
    STRAVA_REFRESH_TOKEN=<refresh_token>

Contributing

  1. Fork the repository

  2. Install dependencies: uv pip install -e ".[dev]"

  3. Create a branch: git checkout -b feature/name

  4. Check the changes:

    ruff format .
    ruff check .
    pytest --cov=src
  5. Create a Pull Request

πŸ“« Support

πŸ“„ License

MIT

Available Tools

4 tools
analyze_activityC

Анализ активности ΠΈΠ· Strava

Args:
    activity_id: ID активности (строка ΠΈΠ»ΠΈ число)
Returns:
    dict: Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π°Π½Π°Π»ΠΈΠ·Π° активности

Inputs: activity_id (required).

analyze_training_loadD

Анализ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

Inputs: activities (required).

get_activity_by_idC

Get activity details from Strava

Args:
    activity_id (Union[str, int]): Activity ID to fetch
    
Returns:
    Dict: Activity details including type, distance, time and other metrics

Inputs: activity_id (required).

get_activity_recommendationsB

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌ Π½Π° основС Π°Π½Π°Π»ΠΈΠ·Π° послСдних активностСй

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.2/5.0

    Scored across 4 tools

    Disambiguation2/5

    There is significant overlap between analyze_activity and get_activity_by_id, as both appear to retrieve and process activity data based on activity_id, making them easily confused. analyze_training_load and get_activity_recommendations are more distinct but still related to activity analysis, creating some ambiguity in the set.

    Naming Consistency3/5

    The naming is mixed with both English and Russian terms (e.g., analyze_activity vs. analyze_training_load in English, but get_activity_recommendations in Russian description), and the verb patterns vary (analyze_ vs. get_). While readable, this inconsistency reduces predictability and coherence.

    Tool Count3/5

    With 4 tools, the count is borderline thin for a Strava server, as it might lack broader functionality like user management, activity creation, or social features. However, it covers core analysis aspects, so it's not severely mismatched but feels slightly under-scoped.

    Completeness2/5

    The tool set is focused on activity analysis and recommendations, but there are significant gaps: no CRUD operations for activities (e.g., create, update, delete), no user profile or authentication tools, and no social or leaderboard features typical of Strava's domain. This will likely cause agent failures for common workflows.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers