Content
# Strava MCP Server
A Model Context Protocol (MCP) server that exposes 20 Strava API tools to Claude. Built with [FastMCP](https://github.com/jlowin/fastmcp).
## Tools
### Athlete
| Tool | Description |
|------|-------------|
| `get_athlete` | Profile: id, name, city, sex, premium status |
| `get_athlete_stats(athlete_id)` | Training totals (recent / YTD / all-time) by sport |
| `get_athlete_zones` | Heart rate and power training zones |
| `get_athlete_shoes` | Gear list with cumulative distance |
### Activities
| Tool | Description |
|------|-------------|
| `list_activities` | Paginated feed with optional date range and sport type filter |
| `get_activity(activity_id)` | Full activity detail: splits, laps, segment efforts |
| `get_activity_laps(activity_id)` | Lap / interval breakdown |
| `get_activity_streams(activity_id)` | Time-series sensor data (HR, power, GPS, cadence, …) |
| `get_activity_zones(activity_id)` | Zone distribution _(requires Strava Summit)_ |
| `update_activity(activity_id)` | Update name, description, trainer, commute, or gear _(requires `activity:write` scope)_ |
### Segments
| Tool | Description |
|------|-------------|
| `get_segment(segment_id)` | Segment details and community stats |
| `list_segment_efforts(segment_id)` | Your efforts on a segment, filterable by date |
| `list_starred_segments` | Your starred segments |
| `get_segment_leaderboard(segment_id)` | Leaderboard with gender / age / weight / date filters |
| `explore_segments(bounds)` | Discover segments within a geographic bounding box |
### Routes
| Tool | Description |
|------|-------------|
| `list_routes` | Your saved routes |
| `get_route(route_id)` | Route detail with segment list |
| `export_route_gpx(route_id)` | Export route as GPX XML |
| `export_route_tcx(route_id)` | Export route as TCX XML |
### Clubs
| Tool | Description |
|------|-------------|
| `list_athlete_clubs` | Clubs you're a member of |
## Setup
### 1. Install dependencies
```bash
cd Strava
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
```
### 2. Create a Strava API application
1. Go to [strava.com/settings/api](https://www.strava.com/settings/api) and create an app.
2. Note your **Client ID** and **Client Secret**.
3. Authorize once to get an access token and refresh token. The easiest way is the [Strava OAuth Playground](https://developers.strava.com/playground/) — request scopes `activity:read_all,profile:read_all`.
### 3. Configure `.env`
```bash
cp .env.example .env # or create from scratch
```
```env
STRAVA_CLIENT_ID=your_client_id
STRAVA_CLIENT_SECRET=your_client_secret
STRAVA_ACCESS_TOKEN=your_initial_access_token
STRAVA_REFRESH_TOKEN=your_refresh_token
```
> **Token rotation note:** Strava rotates the refresh token on every refresh. The server updates both tokens in memory automatically, but does **not** write back to `.env`. If you restart the server more than 6 hours after the last run, the token in `.env` may be stale — re-authorize to get a fresh pair.
### 4. Connect to Claude
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"strava": {
"command": "/path/to/Strava/.venv/bin/fastmcp",
"args": ["run", "/path/to/Strava/strava_server.py"]
}
}
}
```
Then restart Claude Desktop.
## Caveats
- **`get_activity_zones` requires Strava Summit.** Non-subscribers receive a clear 403 error.
- **`get_athlete_shoes` requires `profile:read_all` scope.** Without it the shoes array will be empty.
- **`list_activities` sport type filter is client-side.** The Strava API doesn't support server-side sport type filtering, so `count` may be less than `per_page` after filtering.
- **`get_activity_streams`** only returns streams the device actually recorded — missing stream types are silently omitted by Strava.
- **`update_activity` requires `activity:write` scope.** The default read-only token won't work. Re-authorize via the Strava OAuth flow with `activity:read_all,activity:write` scopes to get a token that can write.
## Enum reference
| Parameter | Tool | Allowed values |
|-----------|------|----------------|
| `gender` | `get_segment_leaderboard` | `"M"`, `"F"` |
| `date_range` | `get_segment_leaderboard` | `"this_year"`, `"this_month"`, `"this_week"`, `"today"` |
| `activity_type` | `explore_segments` | `"riding"`, `"running"` |
| `keys` | `get_activity_streams` | `time`, `distance`, `latlng`, `altitude`, `velocity_smooth`, `heartrate`, `cadence`, `watts`, `temp`, `moving`, `grade_smooth` |
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.