strava-mcp
Syncs Strava activities, laps, splits, segment efforts, zones, gear, and routes to a local SQLite database and provides MCP tools to query and analyze this data, including activity filtering, detailed stats, power analysis, training trends, and custom SQL queries.
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., "@strava-mcpShow my cycling stats from last month"
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-mcp
A local Strava data pipeline and MCP server. Syncs your Strava activities to a SQLite database and exposes everything to Claude via the Model Context Protocol.
What it does
strava_downloader.py— fetches your athlete profile, activities (with laps, splits, segment efforts, and HR/power zones), gear, routes, and starred segments from the Strava API and stores them locally in SQLite. Run it as a cron job for incremental daily syncs.mcp_server.py— an HTTP streamable MCP server (with bearer token auth) that gives Claude tools to query your Strava data conversationally.
Related MCP server: Strava MCP Server
Setup
1. Install dependencies
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt2. Configure credentials
Copy .env.example to .env and fill in your Strava credentials:
cp .env.example .envYou need a Strava API application and an OAuth2 refresh token:
Go to strava.com/settings/api and create an app
Authorize your app to get an authorization code:
https://www.strava.com/oauth/authorize?client_id=YOUR_CLIENT_ID &redirect_uri=http://localhost&response_type=code &scope=activity:read_all,profile:read_allExchange the code for tokens:
curl -X POST https://www.strava.com/oauth/token \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_CLIENT_SECRET \ -d code=AUTHORIZATION_CODE \ -d grant_type=authorization_codeCopy
access_token,refresh_token, andexpires_atinto.env
For the MCP server, generate a bearer token:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"Add it as STRAVA_MCP_AUTH_TOKEN in .env.
3. Sync your data
# First run — last 30 days (fast, to verify everything works)
.venv/bin/python strava_downloader.py --days 30
# Full historical sync (2+ years, respects Strava rate limits automatically)
.venv/bin/python strava_downloader.py
# Re-fetch laps/zones for all activities (if you ran a summary-only import before)
.venv/bin/python strava_downloader.py --fullThe downloader automatically refreshes expired OAuth2 tokens and saves them back to .env.
4. Start the MCP server
.venv/bin/python mcp_server.pyThis starts an HTTP server on port 8080 (default). Connect your MCP client with:
{
"mcpServers": {
"strava": {
"url": "http://localhost:8080/mcp/",
"headers": {
"Authorization": "Bearer YOUR_STRAVA_MCP_AUTH_TOKEN"
}
}
}
}For stdio transport (Claude Desktop local):
.venv/bin/python mcp_server.py --transport stdioCron job (incremental sync)
Add to your crontab for a daily sync at 6 AM:
0 6 * * * cd /path/to/strava-mcp && .venv/bin/python strava_downloader.py >> /var/log/strava-sync.log 2>&1Each incremental run picks up from the most recent activity already in the database.
What Claude can query
Resources (snapshot data):
Athlete profile with lifetime totals
All activities (with pace, speed, and unit conversions pre-computed)
Aggregate stats by sport type
Monthly training trends
Recent activities (last 30 days)
Gear / equipment list
Tools (parameterized queries):
query_activities— filter by sport, date range, distance, HR, power, commute flagget_activity_details— full detail for one activity: laps, metric splits, zone distribution, segment effortsget_segment_efforts— your history on any segment (progression over time)get_power_analysis— power stats with FTP estimateget_training_trends— weekly or monthly aggregates for any metricget_gear_stats— distance logged per bike or shoeget_routes— your saved routesexecute_sql— custom SELECT queries against any table
Database schema
SQLite database at ./strava_activities.db (configurable via STRAVA_DB_PATH).
Table | Contents |
| Athlete profile + YTD/all-time totals |
| All activities — summary + detail fields |
| Lap splits per activity |
| 1 km metric splits per activity |
| Segment efforts within activities |
| Segment master data |
| Your starred segments |
| Bikes and shoes |
| Saved routes |
| HR/power zone distribution per activity |
| Activities with km, pace, speed pre-computed |
| Aggregated by month + sport type |
Rate limits
Strava enforces 100 requests per 15 minutes and 1000 per day. The downloader:
Sleeps 0.6s between activity detail fetches
Automatically waits for the next 15-minute window on a 429 response
Retries 5xx errors up to 3 times with back-off
Production deployment (Linux)
sudo useradd --system --shell /usr/sbin/nologin strava-mcp
sudo mkdir -p /opt/strava-mcp
# Copy files, set up venv, create .env
sudo cp deploy/strava-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now strava-mcpSee deploy/strava-mcp.service for the full systemd unit.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- 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/benniblau/strava-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server