BojanMakivic/strava-activity-mcp-server
If you are the rightful owner of strava-activity-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Strava MCP Server is designed to retrieve user activity data from Strava, providing a seamless integration for applications that require access to fitness and activity metrics.
Strava Activity MCP Server
A small Model Context Protocol (MCP) server that exposes your Strava athlete data to language-model tooling.
After the first browser-based authorization, the server uses the saved refresh_token to automatically refresh your session; no further URL-redirected logins are required on subsequent runs.
This package provides a lightweight MCP server which communicates with the Strava API and exposes a few helper tools (authorization URL, token exchange/refresh, and fetching athlete activities) that language models or other local tools can call.
The project is intended to be used locally (for example with Claude MCP integrations) and is published on PyPI as strava-activity-mcp-server.
Installation
Install from PyPI with pip (recommended inside a virtual environment):
pip install strava-activity-mcp-server
Requirements
- Python >= 3.13 (see
pyproject.toml) - The package depends on
mcp[cli]andrequests(installed from PyPI).
Quick start
After installing, you can run the MCP server using the provided console script or by importing and calling main().
Run via the console script (entry point defined in pyproject.toml):
strava-activity-mcp-server
Or, from Python:
from strava_activity_mcp_server import main
main()
By default the server starts the MCP runtime; when used with an MCP-aware client (for example Msty MCP orsome other MCP integrations such Claude, LM Tool and etc.) the exposed tools become callable.
Authentication (Strava OAuth)
This server requires Strava OAuth credentials to access athlete data. You will need:
- STRAVA_CLIENT_ID
- STRAVA_CLIENT_SECRET
Steps:
-
Create a Strava API application at https://www.strava.com/settings/api and note your Client ID and Client Secret. Use
localhostas the Authorization Callback Domain. -
Initial authorization: call the
strava://auth/urltool to generate an authorization URL (see IMAGE below), open it in your browser, and grant access. This step is only needed the first time to obtain an authorization code. -
Copy the
codefrom the redirected URL (Image below). Use the provided tools to exchange it for access/refresh tokens. -
After the initial authorization, a token file named
strava_mcp_tokens.jsonis created and stored in your home directory (for example on Windows:C:\\Users\\<YourUserName>\\strava_mcp_tokens.json). This file contains yourrefresh_token, which will be used automatically for subsequent logins. After the first authorization you do not need to open the browser flow again; future runs refresh the access token from the locally storedrefresh_token.
Exposed Tools (what the server provides)
The MCP server exposes the following tools (tool IDs shown). These map to functions in src/strava_activity_mcp_server/strava_activity_mcp_server.py and cover both initial authorization and subsequent refresh flows:
strava://auth/url— Build the Strava OAuth authorization URL.- Inputs:
client_id(int, optional; readsSTRAVA_CLIENT_IDif omitted) - Output: Authorization URL string
- Inputs:
strava://auth/refresh— Refresh an access token using a refresh token.- Inputs:
refresh_token(str),client_id(int, optional),client_secret(str, optional) - Output:
{ access_token, refresh_token, expires_at, expires_in }
- Inputs:
strava://athlete/stats— Exchange an authorizationcodefor tokens and then fetch recent activities.- Inputs:
code(str),client_id(int, optional),client_secret(str, optional),after(int, optional),before(int, optional),page(int, optional),per_page(int, optional) - Output:
{ activities, tokens, save }
- Inputs:
strava://athlete/stats-with-token— Fetch recent activities using an existing access token.- Inputs:
access_token(str),after(int, optional),before(int, optional),page(int, optional),per_page(int, optional) - Output: Activity list (JSON)
- Inputs:
strava://auth/save— Save tokens to~\strava_mcp_tokens.json.- Inputs:
tokens(dict) - Output:
{ ok, path }or error
- Inputs:
strava://auth/load— Load tokens from~\strava_mcp_tokens.json.- Inputs: none
- Output:
{ ok, tokens, path }or error
strava://athlete/refresh-and-stats— Load saved refresh token, refresh access token, save it, and fetch activities.- Inputs:
client_id(int, optional),client_secret(str, optional),after(int, optional),before(int, optional),page(int, optional),per_page(int, optional) - Output:
{ activities, tokens }
- Inputs:
strava://session/start— Convenience entry: if tokens exist, refresh and fetch; otherwise return an auth URL to begin initial authorization.- Inputs:
client_id(int, optional),client_secret(str, optional),after(int, optional),before(int, optional),page(int, optional),per_page(int, optional) - Output: Either
{ activities, tokens }or{ auth_url, token_file_checked }
- Inputs:
These tools are intended to be called by MCP clients.
Activity Filtering
The server now supports advanced filtering for Strava activities through URL parameters. The following filter parameters are available for activity-related tools:
after(int, optional): An epoch timestamp to filter activities that have taken place after a certain timebefore(int, optional): An epoch timestamp to filter activities that have taken place before a certain timepage(int, optional): The page number of activities to retrieve (default=1)per_page(int, optional): Number of activities per page (default=30, max=200)
Filtering Examples
- Get activities from the last 30 days:
after=1640995200(epoch timestamp for Jan 1, 2022) - Get activities from a specific date range:
after=1640995200&before=1643673600 - Get the first 10 activities:
page=1&per_page=10 - Get activities from page 2 with 50 per page:
page=2&per_page=50
These filters work with the following tools:
strava://athlete/statsstrava://athlete/stats-with-tokenstrava://athlete/refresh-and-statsstrava://session/start
Example flows
- Get an authorization URL and retrieve tokens
- Call
strava://auth/urlwith yourclient_idand open the returned URL in your browser. - After authorizing, Strava will provide a
code.
- Fetch recent activities
- Use
strava://athlete/statswith a valid access token. If the access token is expired, use the refresh flow to get a new access token.
- Fetch filtered activities
- Get activities from the last 7 days: Use
strava://athlete/stats-with-tokenwithafterparameter set to epoch timestamp - Get paginated results: Use
pageandper_pageparameters to control the number of activities returned - Get activities from a specific date range: Combine
afterandbeforeparameters
Client config example and quick inspector test
Any MCP-capable client can launch the server using a config similar to the following (example file often called config.json. Be sure to enter your values here):
{
"command": "uvx",
"args": [
"strava-activity-mcp-server"
],
"env": {
"STRAVA_CLIENT_ID": "12345",
"STRAVA_CLIENT_SECRET": "e1234a12d12345f12c1f12345a123bba1d12c1"
}
}
To quickly test the server using the Model Context Protocol inspector tool, run:
npx @modelcontextprotocol/inspector uvx strava-activity-mcp-server
This will attempt to start the server with the uvx transport and connect the inspector to the running MCP server instance named strava-activity-mcp-server.
Chat example using MCP in Msty Studio
Contributing
Contributions are welcome. Please open issues or pull requests that include a clear description and tests where applicable.
License
This project is licensed under the GNU GENERAL PUBLIC LICENSE — see the LICENSE file for details.
Links
- Source: repository root
- Documentation note: see
README.mdfor an example MCP configuration