Strava MCP Server
A TypeScript server that acts as a bridge to the Strava API, enabling LLMs to access users' activities, routes, segments, and athlete data through natural language interaction.
r-huijts
README
Strava MCP Server
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.
Natural Language Interaction Examples
Ask your AI assistant questions like these to interact with your Strava data:
Recent Activity & Profile:
- "Show me my recent Strava activities."
- "What were my last 3 rides?"
- "Get my Strava profile information."
- "What's my Strava username?"
Stats:
- "What are my running stats for this year on Strava?"
- "How far have I cycled in total?"
- "Show me my all-time swim totals."
Specific Activities:
- "Give me the details for my last run (activity ID 12345)."
- "What was the average power for activity 987654321?"
- "Did I use my Trek bike for activity 11223344?"
Clubs:
- "What Strava clubs am I in?"
- "List the clubs I've joined."
Segments:
- "List the segments I starred near Boulder, Colorado."
- "Show my favorite segments."
- "Get details for the 'Alpe du Zwift' segment (ID 123456)."
- "Are there any good running segments near Golden Gate Park? Use bounds 37.76,-122.51,37.78,-122.45."
- "Find Cat 1 or HC climbs near coordinates 39.9,-105.3,40.1,-105.1."
- "Star the 'Flagstaff Road Climb' segment (ID 654321) for me."
- "Unstar segment 112233."
Segment Efforts:
- "Show my efforts on the 'Sunshine Canyon' segment (ID 987654) this month."
- "List my attempts on segment 123123 between 2023-01-01 and 2023-06-30."
- "Get the details for my PR effort (effort ID 555666777)."
Routes:
- "List my saved Strava routes."
- "Show the second page of my routes."
- "What is the elevation gain for route 112233?"
- "Get the description for my 'Boulder Loop' route (ID 7654321)."
- "Export my 'Boulder Loop' route (ID 7654321) as a GPX file."
- "Save route 998877 as a TCX file."
Features
- 🏃 Access recent activities, profile, and stats.
- 🗺️ Explore, view, star, and manage segments.
- ⏱️ View detailed activity and segment effort information.
- 📍 List and view details of saved routes.
- 💾 Export routes in GPX or TCX format to the local filesystem.
- 🤖 AI-friendly JSON responses via MCP.
- 🔧 Uses Strava API V3.
Installation & Setup
-
Prerequisites:
- Node.js (v18 or later recommended)
- npm (usually comes with Node.js)
- A Strava Account
-
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:
- Go to your Strava API Settings: https://www.strava.com/settings/api
- Create a new API application (if you don't have one already).
- Crucially: Under "Authorization Callback Domain", enter
localhost
. - Note down your application's Client ID and Client Secret. You will need these shortly.
- Leave the default application settings as they are unless you have specific needs.
-
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:
- The script will first check your
.env
file (creating it if it doesn't exist) for yourSTRAVA_CLIENT_ID
andSTRAVA_CLIENT_SECRET
. - If not found in
.env
, it will prompt you to enter the Client ID and Client Secret you obtained from the Strava API settings page. - It will then display a Strava Authorization URL. Copy this URL.
- Paste the URL into your web browser and navigate to it.
- You will be asked to authorize your application to access your Strava data with the required scopes (
profile:read_all
,activity:read_all
). Click Authorize. - After authorizing, Strava will redirect your browser to a
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 onlocalhost
. - Important: Look at the URL in your browser's address bar. Copy the value of the
code
parameter. It will be a long string of letters and numbers (e.g.,SOME_LONG_CODE
in the example above). - Go back to your terminal where the script is running and paste this authorization code when prompted.
- The script will exchange this code for an Access Token and a Refresh Token.
- It will ask if you want to save these tokens to your
.env
file. Typeyes
ory
and press Enter.
- The script will first check your
-
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):
- If you intend to use the
export-route-gpx
orexport-route-tcx
tools, you need to specify a directory for saving exported files. - Edit your
.env
file and add/update theROUTE_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=
- Replace the placeholder with the absolute path to your desired export directory. Ensure the directory exists and the server has permission to write to it.
- If you intend to use the
-
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 thestrava-mcp
repository. -
Ensure the
command
isnode
and theargs
point to the compileddist/server.js
file. -
Restart your MCP client for the changes to take effect.
-
Usage Examples
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.
- User: "Show my last 5 activities."
- LLM Action: Calls
get-recent-activities
withperPage: 5
.
- LLM Action: Calls
- User: "What was my average heart rate on activity 987654321?"
- LLM Action: Calls
get-activity-details
withactivityId: 987654321
. (The LLM would then parse the response to answer the specific question).
- LLM Action: Calls
- User: "Find cycling segments near 40.01,-105.27,40.03,-105.25 that are Cat 4 or harder."
- LLM Action: Calls
explore-segments
withbounds: "40.01,-105.27,40.03,-105.25"
,activityType: "riding"
,maxCat: 4
.
- LLM Action: Calls
- User: "Save route 12345 as a GPX file."
- LLM Action: Calls
export-route-gpx
withrouteId: 12345
. (RequiresROUTE_EXPORT_PATH
to be configured).
- LLM Action: Calls
API Reference
The server exposes the following MCP tools:
get-recent-activities
Fetches the authenticated user's recent activities.
- When to use: When the user asks about their recent workouts, activities, runs, rides, etc.
- Parameters:
perPage
(optional):- Type:
number
- Description: Number of activities to retrieve.
- Default: 30
- Type:
- Output: Formatted text list of recent activities (Name, ID, Distance, Date).
- Errors: Missing/invalid token, Strava API errors.
get-athlete-profile
Fetches the profile information for the authenticated athlete.
- When to use: When the user asks for their profile details, username, location, weight, premium status, etc.
- Parameters: None
- Output: Formatted text string with profile details.
- Errors: Missing/invalid token, Strava API errors.
get-athlete-stats
Fetches activity statistics (recent, YTD, all-time) for the authenticated athlete.
- When to use: When the user asks for their overall statistics, totals for runs/rides/swims, personal records (longest ride, biggest climb).
- Parameters: None
- Output: Formatted text summary of stats, respecting user's measurement preference.
- Errors: Missing/invalid token, Strava API errors.
get-activity-details
Fetches detailed information about a specific activity using its ID.
- When to use: When the user asks for details about a specific activity identified by its ID.
- Parameters:
activityId
(required):- Type:
number
- Description: The unique identifier of the activity.
- Type:
- Output: Formatted text string with detailed activity information (type, date, distance, time, speed, HR, power, gear, etc.), respecting user's measurement preference.
- Errors: Missing/invalid token, Invalid
activityId
, Strava API errors.
list-athlete-clubs
Lists the clubs the authenticated athlete is a member of.
- When to use: When the user asks about the clubs they have joined.
- Parameters: None
- Output: Formatted text list of clubs (Name, ID, Sport, Members, Location).
- Errors: Missing/invalid token, Strava API errors.
list-starred-segments
Lists the segments starred by the authenticated athlete.
- When to use: When the user asks about their starred or favorite segments.
- Parameters: None
- Output: Formatted text list of starred segments (Name, ID, Type, Distance, Grade, Location).
- Errors: Missing/invalid token, Strava API errors.
get-segment
Fetches detailed information about a specific segment using its ID.
- When to use: When the user asks for details about a specific segment identified by its ID.
- Parameters:
segmentId
(required):- Type:
number
- Description: The unique identifier of the segment.
- Type:
- Output: Formatted text string with detailed segment information (distance, grade, elevation, location, stars, efforts, etc.), respecting user's measurement preference.
- Errors: Missing/invalid token, Invalid
segmentId
, Strava API errors.
explore-segments
Searches for popular segments within a given geographical area (bounding box).
- When to use: When the user wants to find or discover segments in a specific geographic area, optionally filtering by activity type or climb category.
- Parameters:
bounds
(required):- Type:
string
- Description: Comma-separated:
south_west_lat,south_west_lng,north_east_lat,north_east_lng
.
- Type:
activityType
(optional):- Type:
string
("running"
or"riding"
) - Description: Filter by activity type.
- Type:
minCat
(optional):- Type:
number
(0-5) - Description: Minimum climb category. Requires
activityType: 'riding'
.
- Type:
maxCat
(optional):- Type:
number
(0-5) - Description: Maximum climb category. Requires
activityType: 'riding'
.
- Type:
- Output: Formatted text list of found segments (Name, ID, Climb Cat, Distance, Grade, Elevation).
- Errors: Missing/invalid token, Invalid
bounds
format, Invalid filter combination, Strava API errors.
star-segment
Stars or unstars a specific segment for the authenticated athlete.
- When to use: When the user explicitly asks to star, favorite, unstar, or unfavorite a specific segment identified by its ID.
- Parameters:
segmentId
(required):- Type:
number
- Description: The unique identifier of the segment.
- Type:
starred
(required):- Type:
boolean
- Description:
true
to star,false
to unstar.
- Type:
- Output: Success message confirming the action and the segment's new starred status.
- Errors: Missing/invalid token, Invalid
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.
- When to use: When the user asks for details about a specific segment effort identified by its ID.
- Parameters:
effortId
(required):- Type:
number
- Description: The unique identifier of the segment effort.
- Type:
- Output: Formatted text string with detailed effort information (segment name, activity ID, time, distance, HR, power, rank, etc.).
- Errors: Missing/invalid token, Invalid
effortId
, Strava API errors.
list-segment-efforts
Lists the authenticated athlete's efforts on a given segment, optionally filtered by date.
- When to use: When the user asks to list their efforts or attempts on a specific segment, possibly within a date range.
- Parameters:
segmentId
(required):- Type:
number
- Description: The ID of the segment.
- Type:
startDateLocal
(optional):- Type:
string
(ISO 8601 format) - Description: Filter efforts starting after this date-time.
- Type:
endDateLocal
(optional):- Type:
string
(ISO 8601 format) - Description: Filter efforts ending before this date-time.
- Type:
perPage
(optional):- Type:
number
- Description: Number of results per page.
- Default: 30
- Type:
- Output: Formatted text list of matching segment efforts.
- Errors: Missing/invalid token, Invalid
segmentId
, Invalid date format, Strava API errors.
list-athlete-routes
Lists the routes created by the authenticated athlete.
- When to use: When the user asks to see the routes they have created or saved.
- Parameters:
page
(optional):- Type:
number
- Description: Page number for pagination.
- Type:
perPage
(optional):- Type:
number
- Description: Number of routes per page.
- Default: 30
- Type:
- Output: Formatted text list of routes (Name, ID, Type, Distance, Elevation, Date).
- Errors: Missing/invalid token, Strava API errors.
get-route
Fetches detailed information for a specific route using its ID.
- When to use: When the user asks for details about a specific route identified by its ID.
- Parameters:
routeId
(required):- Type:
number
- Description: The unique identifier of the route.
- Type:
- Output: Formatted text string with route details (Name, ID, Type, Distance, Elevation, Est. Time, Description, Segment Count).
- Errors: Missing/invalid token, Invalid
routeId
, Strava API errors.
export-route-gpx
Exports a specific route in GPX format and saves it locally.
- When to use: When the user explicitly asks to export or save a specific route as a GPX file.
- Prerequisite: The
ROUTE_EXPORT_PATH
environment variable must be correctly configured on the server. - Parameters:
routeId
(required):- Type:
number
- Description: The unique identifier of the route.
- Type:
- Output: Success message indicating the save location, or an error message.
- Errors: Missing/invalid token, Missing/invalid
ROUTE_EXPORT_PATH
, File system errors (permissions, disk space), InvalidrouteId
, Strava API errors.
export-route-tcx
Exports a specific route in TCX format and saves it locally.
- When to use: When the user explicitly asks to export or save a specific route as a TCX file.
- Prerequisite: The
ROUTE_EXPORT_PATH
environment variable must be correctly configured on the server. - Parameters:
routeId
(required):- Type:
number
- Description: The unique identifier of the route.
- Type:
- Output: Success message indicating the save location, or an error message.
- Errors: Missing/invalid token, Missing/invalid
ROUTE_EXPORT_PATH
, File system errors (permissions, disk space), InvalidrouteId
, Strava API errors.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details. (Assuming MIT, update if different)
Acknowledgments
- Strava for providing the public API.
- The Model Context Protocol (MCP) community.
Token Handling
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.
Authentication Script Walkthrough
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:
1. Create a Strava API Application
Before running the script, go to https://www.strava.com/settings/api and create a new application:
- Enter your application details (name, website, description)
- Important: Set "Authorization Callback Domain" to
localhost
- Note down your Client ID and Client Secret
2. Run the Setup Script
# In your strava-mcp directory
npx ts-node scripts/setup-auth.ts
You'll see a welcome message:
--- Strava API Token Setup ---
3. Enter Client Credentials
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]
4. Browser Authorization
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=...)
- Open this URL in your browser
- Log in to Strava if needed
- Click "Authorize" on the permission screen
- You'll be redirected to
localhost
(which will show a connection error - this is normal) - Look at your browser's address bar to find the authorization code:
The code is the part afterhttp://localhost/?state=&code=1a2b3c4d5e6f7g8h9i0j&scope=read,activity:read_all,profile:read_all
code=
and before&scope=
5. Complete the OAuth Flow
- Copy the authorization code from your browser
- Return to your terminal and paste the code when prompted:
Paste the authorization code here: 1a2b3c4d5e6f7g8h9i0j
- The script will exchange this code for access and refresh tokens
6. Save Tokens to .env
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
7. Build and Start the Server
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.
Recommended Servers
Crypto Price & Market Analysis MCP Server
A Model Context Protocol (MCP) server that provides comprehensive cryptocurrency analysis using the CoinCap API. This server offers real-time price data, market analysis, and historical trends through an easy-to-use interface.
MCP PubMed Search
Server to search PubMed (PubMed is a free, online database that allows users to search for biomedical and life sciences literature). I have created on a day MCP came out but was on vacation, I saw someone post similar server in your DB, but figured to post mine.
dbt Semantic Layer MCP Server
A server that enables querying the dbt Semantic Layer through natural language conversations with Claude Desktop and other AI assistants, allowing users to discover metrics, create queries, analyze data, and visualize results.
mixpanel
Connect to your Mixpanel data. Query events, retention, and funnel data from Mixpanel analytics.

Sequential Thinking MCP Server
This server facilitates structured problem-solving by breaking down complex issues into sequential steps, supporting revisions, and enabling multiple solution paths through full MCP integration.

Nefino MCP Server
Provides large language models with access to news and information about renewable energy projects in Germany, allowing filtering by location, topic (solar, wind, hydrogen), and date range.
Vectorize
Vectorize MCP server for advanced retrieval, Private Deep Research, Anything-to-Markdown file extraction and text chunking.
Mathematica Documentation MCP server
A server that provides access to Mathematica documentation through FastMCP, enabling users to retrieve function documentation and list package symbols from Wolfram Mathematica.
kb-mcp-server
An MCP server aimed to be portable, local, easy and convenient to support semantic/graph based retrieval of txtai "all in one" embeddings database. Any txtai embeddings db in tar.gz form can be loaded
Research MCP Server
The server functions as an MCP server to interact with Notion for retrieving and creating survey data, integrating with the Claude Desktop Client for conducting and reviewing surveys.