A Model Context Protocol (MCP) server that connects to Strava API, providing tools to access Strava data through LLMs
This project implements a Model Context Protocol (MCP) server in TypeScript that acts as a bridge to the Strava API. It exposes Strava data and functionalities as "tools" that Large Language Models (LLMs) can utilize through the MCP standard.
Ask your AI assistant questions like these to interact with your Strava data:
Recent Activity & Profile:
Stats:
Specific Activities:
Clubs:
Segments:
Segment Efforts:
Routes:
Prerequisites:
Clone Repository:
git clone <repository_url> strava-mcp
cd strava-mcp
(Replace <repository_url>
with the actual URL)
Install Dependencies:
npm install
Strava API Application Setup:
localhost
.Generate API Tokens using the Setup Script:
This project includes a script to handle the Strava OAuth flow and obtain the necessary API tokens.
Run the setup script:
npx ts-node scripts/setup-auth.ts
Follow the Prompts:
.env
file (creating it if it doesn't exist) for your STRAVA_CLIENT_ID
and STRAVA_CLIENT_SECRET
..env
, it will prompt you to enter the Client ID and Client Secret you obtained from the Strava API settings page.profile:read_all
, activity:read_all
). Click Authorize.localhost
URL (e.g., http://localhost/?state=&code=SOME_LONG_CODE&scope=read,activity:read_all,profile:read_all
). This page might show a "This site can't be reached" error, which is expected and normal because you aren't running a web server on localhost
.code
parameter. It will be a long string of letters and numbers (e.g., SOME_LONG_CODE
in the example above)..env
file. Type yes
or y
and press Enter.Your .env
file should now contain:
STRAVA_CLIENT_ID=YOUR_CLIENT_ID
STRAVA_CLIENT_SECRET=YOUR_CLIENT_SECRET
STRAVA_ACCESS_TOKEN=GENERATED_ACCESS_TOKEN
STRAVA_REFRESH_TOKEN=GENERATED_REFRESH_TOKEN
Configure Export Path (Optional):
export-route-gpx
or export-route-tcx
tools, you need to specify a directory for saving exported files..env
file and add/update the ROUTE_EXPORT_PATH
variable:
# Optional: Define an *absolute* path for saving exported route files (GPX/TCX)
# Ensure this directory exists and the server process has write permissions.
# Example: ROUTE_EXPORT_PATH=/Users/your_username/strava-exports
ROUTE_EXPORT_PATH=
Build the Project:
npm run build
Run the Server:
npm start
The server will connect via Stdio and log status messages to stderr.
Configure Claude Desktop (or other MCP Client):
To allow an MCP client (like Claude Desktop) to connect to your locally running server, you need to update its configuration.
For Claude Desktop, find the configuration file (e.g., ~/Library/Application Support/Claude/claude_desktop_config.json
on macOS).
Add or update the mcpServers
section:
{
"mcpServers": {
"strava-mcp-local": {
"command": "node",
"args": [
"/absolute/path/to/your/strava-mcp/dist/server.js"
],
// Environment variables are read from the .env file by the server,
// so you typically don't need to set them here unless overriding.
}
}
}
Important: Replace /absolute/path/to/your/strava-mcp/
with the actual, full path to where you cloned the strava-mcp
repository.
Ensure the command
is node
and the args
point to the compiled dist/server.js
file.
Restart your MCP client for the changes to take effect.
An LLM assistant (like Claude) can use the tools provided by this server based on natural language prompts. The assistant will typically identify the correct tool and extract the necessary parameters from the user's request.
get-recent-activities
with perPage: 5
.get-activity-details
with activityId: 987654321
. (The LLM would then parse the response to answer the specific question).explore-segments
with bounds: "40.01,-105.27,40.03,-105.25"
, activityType: "riding"
, maxCat: 4
.export-route-gpx
with routeId: 12345
. (Requires ROUTE_EXPORT_PATH
to be configured).The server exposes the following MCP tools:
get-recent-activities
Fetches the authenticated user's recent activities.
perPage
(optional):
number
get-athlete-profile
Fetches the profile information for the authenticated athlete.
get-athlete-stats
Fetches activity statistics (recent, YTD, all-time) for the authenticated athlete.
get-activity-details
Fetches detailed information about a specific activity using its ID.
activityId
(required):
number
activityId
, Strava API errors.list-athlete-clubs
Lists the clubs the authenticated athlete is a member of.
list-starred-segments
Lists the segments starred by the authenticated athlete.
get-segment
Fetches detailed information about a specific segment using its ID.
segmentId
(required):
number
segmentId
, Strava API errors.explore-segments
Searches for popular segments within a given geographical area (bounding box).
bounds
(required):
string
south_west_lat,south_west_lng,north_east_lat,north_east_lng
.activityType
(optional):
string
("running"
or "riding"
)minCat
(optional):
number
(0-5)activityType: 'riding'
.maxCat
(optional):
number
(0-5)activityType: 'riding'
.bounds
format, Invalid filter combination, Strava API errors.star-segment
Stars or unstars a specific segment for the authenticated athlete.
segmentId
(required):
number
starred
(required):
boolean
true
to star, false
to unstar.segmentId
, Strava API errors (e.g., segment not found, rate limit).get-segment-effort
Fetches detailed information about a specific segment effort using its ID.
effortId
(required):
number
effortId
, Strava API errors.list-segment-efforts
Lists the authenticated athlete's efforts on a given segment, optionally filtered by date.
segmentId
(required):
number
startDateLocal
(optional):
string
(ISO 8601 format)endDateLocal
(optional):
string
(ISO 8601 format)perPage
(optional):
number
segmentId
, Invalid date format, Strava API errors.list-athlete-routes
Lists the routes created by the authenticated athlete.
page
(optional):
number
perPage
(optional):
number
get-route
Fetches detailed information for a specific route using its ID.
routeId
(required):
number
routeId
, Strava API errors.export-route-gpx
Exports a specific route in GPX format and saves it locally.
ROUTE_EXPORT_PATH
environment variable must be correctly configured on the server.routeId
(required):
number
ROUTE_EXPORT_PATH
, File system errors (permissions, disk space), Invalid routeId
, Strava API errors.export-route-tcx
Exports a specific route in TCX format and saves it locally.
ROUTE_EXPORT_PATH
environment variable must be correctly configured on the server.routeId
(required):
number
ROUTE_EXPORT_PATH
, File system errors (permissions, disk space), Invalid routeId
, Strava API errors.Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details. (Assuming MIT, update if different)
This server implements automatic token refreshing. When the initial access token expires (typically after 6 hours), the server will automatically use the refresh token stored in .env
to obtain a new access token and refresh token. These new tokens are then updated in both the running process and the .env
file, ensuring continuous operation.
You only need to run the scripts/setup-auth.ts
script once for the initial setup.
The setup-auth.ts
script makes it easy to set up authentication with the Strava API. Here's a detailed walkthrough with screenshots and explanations:
Before running the script, go to https://www.strava.com/settings/api and create a new application:
localhost
# In your strava-mcp directory
npx ts-node scripts/setup-auth.ts
You'll see a welcome message:
--- Strava API Token Setup ---
If your .env
file doesn't already contain your Strava API credentials, you'll be prompted to enter them:
Enter your Strava Application Client ID: [your_client_id]
Enter your Strava Application Client Secret: [your_client_secret]
The script will generate an authorization URL:
Step 1: Authorize Application
Please visit the following URL in your browser:
https://www.strava.com/oauth/authorize?client_id=12345&response_type=code&redirect_uri=http://localhost&approval_prompt=force&scope=profile:read_all,activity:read_all
After authorizing, Strava will redirect you to http://localhost.
Copy the 'code' value from the URL in your browser's address bar.
(e.g., http://localhost/?state=&code=THIS_PART&scope=...)
localhost
(which will show a connection error - this is normal)http://localhost/?state=&code=1a2b3c4d5e6f7g8h9i0j&scope=read,activity:read_all,profile:read_all
The code is the part after code=
and before &scope=
Paste the authorization code here: 1a2b3c4d5e6f7g8h9i0j
When asked to save the tokens to your .env file, enter "yes":
Do you want to save these tokens to your .env file? (yes/no): yes
✅ Tokens successfully saved to .env file.
Your .env
file will now contain all required credentials:
STRAVA_CLIENT_ID=your_client_id
STRAVA_CLIENT_SECRET=your_client_secret
STRAVA_ACCESS_TOKEN=your_generated_access_token
STRAVA_REFRESH_TOKEN=your_generated_refresh_token
Now that authentication is set up, build and start the server:
npm run build
npm start
You should see:
Starting Strava MCP Server...
Strava MCP Server connected via Stdio. Tools registered.
With these steps completed, your MCP server is ready to provide Strava data to compatible LLM clients, with automatic token refresh handling.