Strava MCP server — 19 tools for activities, segments, routes, and clubs via the Strava API
Strava MCP Server
A Model Context Protocol (MCP) server that exposes 19 Strava API tools to Claude. Built with 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) |
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
cd Strava
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
2. Create a Strava API application
- Go to strava.com/settings/api and create an app.
- Note your Client ID and Client Secret.
- Authorize once to get an access token and refresh token. The easiest way is the Strava OAuth Playground — request scopes
activity:read_all,profile:read_all.
3. Configure .env
cp .env.example .env # or create from scratch
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.envmay 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):
{
"mcpServers": {
"strava": {
"command": "/path/to/Strava/.venv/bin/fastmcp",
"args": ["run", "/path/to/Strava/strava_server.py"]
}
}
}
Then restart Claude Desktop.
Caveats
get_activity_zonesrequires Strava Summit. Non-subscribers receive a clear 403 error.get_athlete_shoesrequiresprofile:read_allscope. Without it the shoes array will be empty.list_activitiessport type filter is client-side. The Strava API doesn't support server-side sport type filtering, socountmay be less thanper_pageafter filtering.get_activity_streamsonly returns streams the device actually recorded — missing stream types are silently omitted by Strava.
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 |