Skip to main content
Glama
rbctmz

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: Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π°Π½Π°Π»ΠΈΠ·Π° активности
ParametersJSON Schema
NameRequiredDescriptionDefault
activity_idYes

TDQS

C2.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool returns 'Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π°Π½Π°Π»ΠΈΠ·Π° активности' (results of activity analysis), which implies read-only behavior but lacks details on what the analysis entails, potential side effects, or performance considerations. This is insufficient for a tool with no annotation coverage.

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 concise and well-structured: it starts with the purpose, lists arguments and returns in a clear format. However, the inclusion of 'Args:' and 'Returns:' sections adds some redundancy, as this information could be inferred from the schema, slightly reducing efficiency.

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

Completeness2/5

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

Given the lack of annotations, no output schema, and low schema description coverage (0%), the description is incomplete. It doesn't detail what 'analysis' involves, the return structure, or error handling, making it inadequate for an analysis tool with one parameter and sibling alternatives.

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

Parameters3/5

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

The description adds minimal semantics beyond the input schema: it specifies that 'activity_id' is 'ID активности (строка ΠΈΠ»ΠΈ число)' (activity ID, string or number), which matches the schema's 'anyOf' type. With schema description coverage at 0%, this provides basic clarification, but it doesn't explain format, sourcing, or constraints, so it only meets the baseline.

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 states the tool's purpose clearly: 'Анализ активности ΠΈΠ· Strava' (Analysis of activity from Strava). This specifies the verb ('analyze') and resource ('activity from Strava'), making it understandable. However, it doesn't explicitly differentiate from sibling tools like 'get_activity_by_id' or 'analyze_training_load', which prevents a perfect score.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It mentions 'activity_id' as an argument but doesn't explain scenarios where analysis is preferred over retrieval (e.g., 'get_activity_by_id') or other analysis tools (e.g., 'analyze_training_load'), leaving usage ambiguous.

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

analyze_training_loadD

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

ParametersJSON Schema
NameRequiredDescriptionDefault
activitiesYes

TDQS

D1.3/5.0
Behavior1/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 but fails completely. It doesn't indicate whether this is a read or write operation, what permissions might be required, whether it's computationally intensive, what format the analysis takes, or any behavioral characteristics. The single Russian phrase provides zero behavioral context beyond the literal meaning of 'analysis'.

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

Conciseness2/5

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

While technically concise with just two Russian words, this represents under-specification rather than effective conciseness. The description is too brief to be useful - it doesn't front-load important information or provide any meaningful structure. Every sentence should earn its place, but here there's essentially no content to evaluate for efficiency.

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

Completeness1/5

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

Given the complexity (analysis tool with object array input), no annotations, no output schema, and 0% schema description coverage, the description is completely inadequate. It doesn't explain what the tool does, how to use it, what input it expects, what output it produces, or how it differs from sibling tools. For an analysis tool with complex input, this minimal description fails to provide necessary context.

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

Parameters1/5

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

The schema has 0% description coverage for its single parameter 'activities', and the tool description provides absolutely no information about what this parameter should contain. With a complex array of objects parameter, the description fails to explain what activities data is expected, what fields they should have, or how the analysis uses this input. The description adds zero value beyond the bare schema.

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

Purpose2/5

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

The description 'Анализ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ' is a tautology that essentially restates the tool name 'analyze_training_load' in Russian. It doesn't specify what analysis is performed, what resource is analyzed, or how this differs from sibling tools like 'analyze_activity'. The description provides minimal value beyond the tool name itself.

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

Usage Guidelines1/5

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

The description provides absolutely no guidance about when to use this tool versus alternatives. With sibling tools like 'analyze_activity', 'get_activity_by_id', and 'get_activity_recommendations', there's no indication of when this training load analysis tool is appropriate versus those other analysis/retrieval tools. No context, exclusions, or alternatives are mentioned.

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

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
ParametersJSON Schema
NameRequiredDescriptionDefault
activity_idYes

TDQS

C2.9/5.0
Behavior2/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 states the tool fetches activity details but lacks critical information: it doesn't specify if this is a read-only operation, what permissions are required, potential rate limits, error handling, or data freshness. The description is minimal and fails to provide adequate behavioral context for safe and effective use.

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 appropriately sized and front-loaded: the first sentence states the purpose clearly, followed by structured 'Args' and 'Returns' sections. There's no wasted text, and the information is organized efficiently. However, the use of 'Dict' in the return section is vague and could be more precise, slightly reducing clarity.

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

Completeness2/5

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

Given the tool's complexity (a read operation with one parameter) and lack of annotations and output schema, the description is incomplete. It doesn't explain the return structure beyond 'Dict' with examples, missing details like error responses, pagination, or data types. For a tool interacting with an external API like Strava, more context on authentication or limitations is needed for reliable use.

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

Parameters3/5

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

The description adds some value beyond the input schema by explaining that 'activity_id' is used to fetch activity details, but schema description coverage is 0%, meaning the schema provides no descriptions. The description compensates slightly by clarifying the parameter's role, but it doesn't detail format constraints (e.g., ID sources or validation rules). With one parameter and low schema coverage, this is a baseline adequate explanation.

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's purpose: 'Get activity details from Strava' specifies the verb (get) and resource (activity details). It distinguishes from siblings like 'analyze_activity' or 'get_activity_recommendations' by focusing on retrieval rather than analysis or recommendations. However, it doesn't explicitly contrast with siblings, keeping it at 4 instead of 5.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention siblings like 'analyze_activity' or 'get_activity_recommendations', nor does it specify prerequisites or contexts for usage. The only implied usage is fetching details for a specific activity ID, but this is basic and insufficient for effective tool selection.

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

get_activity_recommendationsB

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

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool gets recommendations based on analysis of recent activities, but doesn't describe how it works (e.g., what data it accesses, whether it's read-only or modifies data, response format, or any limitations like rate limits). This is a significant gap for a tool with no annotation coverage.

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

Conciseness5/5

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

The description is a single, clear sentence in Russian: 'ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌ Π½Π° основС Π°Π½Π°Π»ΠΈΠ·Π° послСдних активностСй'. It's front-loaded with the core purpose and has zero waste, making it highly efficient and easy to parse.

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

Completeness2/5

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

Given no annotations, no output schema, and a simple input schema with 0 parameters, the description is incomplete. It states what the tool does but lacks crucial behavioral context (e.g., how it analyzes activities, what data it returns, any side effects). For a recommendation tool, this leaves the agent with insufficient information to use it effectively.

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

Parameters4/5

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

The input schema has 0 parameters with 100% coverage, so no parameters need documentation. The description doesn't add parameter details, which is appropriate here. Baseline is 4 for zero parameters, as there's nothing to compensate for, and the description doesn't introduce unnecessary complexity.

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's purpose: 'ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ Ρ‚Ρ€Π΅Π½ΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌ Π½Π° основС Π°Π½Π°Π»ΠΈΠ·Π° послСдних активностСй' (Get training recommendations based on analysis of recent activities). It specifies both the action (get recommendations) and the resource (training recommendations), and distinguishes it from siblings like analyze_activity or get_activity_by_id by focusing on recommendations rather than analysis or retrieval. However, it doesn't explicitly differentiate from analyze_training_load, which might be related, keeping it from a perfect score.

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

Usage Guidelines2/5

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

The description provides no explicit guidance on when to use this tool versus alternatives. It implies usage for getting recommendations based on recent activities, but doesn't specify prerequisites, when not to use it, or name alternatives like analyze_training_load for comparison. This leaves the agent with minimal context for tool selection.

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

TDQS

C2.2/5.0
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
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

  • A
    license
    B
    quality
    F
    maintenance
    A Model Context Protocol server that provides language models with access to Strava API data, allowing them to query and analyze athlete activities from Strava.
    4
    22
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that enables language models to interact with Strava data, including activities, athlete statistics, routes, achievements, and social features.
    6
    MIT

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/rbctmz/mcp-server-strava'

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