mcp-server-strava
Allows analysis of Strava workouts and provides training recommendations based on Strava data using the Model Context Protocol SDK
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-stravaanalyze my last 5 running activities and give me training recommendations"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Strava API integration with Model Context Protocol (MCP) SDK
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
Go to the API settings page
Create an application:
Application Name: MCP Strava Integration
Category: Training Analysis
Website: http://localhost
Authorization Callback Domain: localhost
Setting up the environment
Create a file with environment variables:
cp .env-template .envGet access tokens:
python scripts/auth.pyCheck the setting:
mcp dev src/server.py curl -X GET "http://localhost:8000/activities"
π API and examples
Resources and Tools
Type | Name | Description |
Resource |
| List of activities |
Resource |
| Activity details |
Resource |
| Training zones |
Resource |
| Athlete's clubs |
Resource |
| Equipment Information |
Tool |
| Training Analysis |
Tool |
| Load analysis |
Tool |
| 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
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
Token protection:
.envto.gitignoreGitHub Secrets for CI/CD
Rate limiting: 100 requests/15 min
Setting up secrets:
# Π GitHub: Settings β Secrets β Actions STRAVA_CLIENT_ID=<client_id> STRAVA_CLIENT_SECRET=<client_secret> STRAVA_REFRESH_TOKEN=<refresh_token>
Contributing
Fork the repository
Install dependencies:
uv pip install -e ".[dev]"Create a branch:
git checkout -b feature/nameCheck the changes:
ruff format . ruff check . pytest --cov=srcCreate a Pull Request
π« Support
GitHub Issues: create issue
π License
Available Tools
4 toolsanalyze_activityC
ΠΠ½Π°Π»ΠΈΠ· Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ ΠΈΠ· Strava
Args:
activity_id: ID Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ (ΡΡΡΠΎΠΊΠ° ΠΈΠ»ΠΈ ΡΠΈΡΠ»ΠΎ)
Returns:
dict: Π Π΅Π·ΡΠ»ΡΡΠ°ΡΡ Π°Π½Π°Π»ΠΈΠ·Π° Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠΈ
| Name | Required | Description | Default |
|---|---|---|---|
| activity_id | Yes |
TDQS
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.
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.
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.
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.
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.
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
ΠΠ½Π°Π»ΠΈΠ· ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΎΡΠ½ΠΎΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠΈ
| Name | Required | Description | Default |
|---|---|---|---|
| activities | Yes |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| activity_id | Yes |
TDQS
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.
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.
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.
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.
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.
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
ΠΠΎΠ»ΡΡΠΈΡΡ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ ΠΏΠΎ ΡΡΠ΅Π½ΠΈΡΠΎΠ²ΠΊΠ°ΠΌ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π°Π½Π°Π»ΠΈΠ·Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡ Π°ΠΊΡΠΈΠ²Π½ΠΎΡΡΠ΅ΠΉ
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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
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.
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.
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.
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
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
Strava MCP tools for AI: athletes, activities, segments, clubs, routes. Powered by HAPI MCP server.
A Model Context Protocol (MCP) application for automated GitHub PR analysis and issue management.β¦
Model Context Protocol server for Studex tools, notifications, and profile integrations
Collect Apple Health data from your wearables through the Context app and query it via MCP
Related MCP Servers
- AlicenseBqualityFmaintenanceA Model Context Protocol server that provides language models with access to Strava API data, allowing them to query and analyze athlete activities from Strava.422MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables language models to interact with Strava data, including activities, athlete statistics, routes, achievements, and social features.6MIT
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables users to access Strava fitness data, including user activities, activity details, segments, and leaderboards through a structured API interface.34MIT
- AlicenseAqualityAmaintenanceModel Context Protocol server for VK (VKontakte) social network API191329MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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