strava-mcp
strava-mcp
MCP server for the Strava API v3. Exposes Strava data — activities, segments, routes, clubs, gear, and streams — as tools that any MCP client (Claude Desktop, Claude Code, etc.) can call.
Read-only by default. Pass --write to enable mutating tools (create/update activities, star segments).
OpenClaw-specific onboarding and sidecar setup: OPENCLAW.md.
Getting started
1. Create a Strava API application
Go to https://www.strava.com/settings/api and create an application. Note your Client ID and Client Secret.
2. Set up credentials
cp .env.example .envAdd your STRAVA_CLIENT_ID and STRAVA_CLIENT_SECRET to .env.
3. Build
pnpm install
pnpm build4. Authenticate
pnpm authThis opens your browser to authorize with Strava. After you approve, it automatically exchanges the code for tokens and saves STRAVA_ACCESS_TOKEN and STRAVA_REFRESH_TOKEN to your .env file. All scopes are requested (read_all, profile:read_all, activity:read_all, activity:write).
5. Test locally
pnpm inspectOpens the MCP Inspector web UI where you can browse tools and call them interactively. Credentials are loaded from .env automatically.
You can also run the server directly:
pnpm start6. Configure your MCP client
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"strava": {
"command": "node",
"args": ["/absolute/path/to/strava-mcp/build/index.js"],
"env": {
"STRAVA_ACCESS_TOKEN": "your-access-token"
}
}
}
}To enable write tools (create/update activities, star segments), add "--write" to args:
{
"mcpServers": {
"strava": {
"command": "node",
"args": ["/absolute/path/to/strava-mcp/build/index.js", "--write"],
"env": {
"STRAVA_ACCESS_TOKEN": "your-access-token"
}
}
}
}Claude Code
claude mcp add strava node /absolute/path/to/strava-mcp/build/index.jsAutomatic token refresh
Strava access tokens expire. To enable automatic refresh, provide all four env vars:
{
"env": {
"STRAVA_ACCESS_TOKEN": "your-access-token",
"STRAVA_REFRESH_TOKEN": "your-refresh-token",
"STRAVA_CLIENT_ID": "your-client-id",
"STRAVA_CLIENT_SECRET": "your-client-secret"
}
}When a request returns 401 and refresh credentials are available, the server will automatically request a new access token from Strava's OAuth endpoint and retry the request.
Environment variables
Variable | Required | Description |
| Yes | Strava OAuth2 bearer token |
| No | Enables automatic token refresh on 401 |
| No | Required alongside refresh token |
| No | Required alongside refresh token |
Tools
Read tools (always available)
Athlete
Tool | Description |
| Get the authenticated athlete's profile |
| Get athlete stats (totals, recent, YTD, all-time) |
| Get heart rate and power zones |
Activities
Tool | Description |
| List the athlete's activities (filterable by |
| Get full details of a specific activity |
| List comments on an activity |
| List athletes who kudoed an activity |
| List laps of an activity |
| Get heart rate/power zones for an activity |
| Get time-series data (heartrate, power, cadence, GPS, etc.) |
Segments
Tool | Description |
| Get details of a specific segment |
| Find popular segments within a bounding box |
| List the athlete's starred segments |
| Get details of a segment effort |
| List efforts on a segment, optionally filtered by date |
| Get data streams for a segment |
| Get data streams for a segment effort |
Routes
Tool | Description |
| Get details of a specific route |
| List routes created by an athlete |
| Get data streams for a route |
Clubs
Tool | Description |
| Get details of a specific club |
| List the athlete's clubs |
| List members of a club |
| List recent activities in a club |
Gear
Tool | Description |
| Get details of a piece of equipment |
Write tools (requires --write flag)
Tool | Description |
| Create a manual activity |
| Update an existing activity (name, description, sport type, gear, etc.) |
| Star or unstar a segment |
Documentation
Use cases — example prompts and what you can do with the server
Architecture — file structure, data flow, and component responsibilities
Design decisions — rationale behind the read/write split, token refresh strategy, thin client approach, and other trade-offs