Skip to main content
Glama
Strava MCP Server

Strava MCP Server

by esowder22

Strava MCP Server

A small, read-only Model Context Protocol server that gives Claude live access to your personal Strava data — activities, splits, heart-rate/pace streams, zones, and lifetime totals — so it can coach off your real training instead of manual exports.

Runs in Strava "single-player mode": it only ever connects your own account.

What it exposes

All tools are reads. The server never creates, edits, or deletes anything on Strava.

Tool

What it returns

get_athlete

Your profile (name, location, weight, FTP if set)

get_stats

Lifetime, YTD, and last-4-weeks totals per sport

list_activities

Recent activities, paginated, with optional date filters

get_activity

Full detail for one activity (splits, pace, HR, power, elevation)

get_activity_streams

Time-series streams for detailed analysis

get_athlete_zones

Configured heart-rate and power zones

Related MCP server: Strava MCP Server

Prerequisites

  • Python 3.10+

  • A Strava account with an active subscription (required to create an API app)

Setup

1. Create a Strava API application

  1. Go to https://www.strava.com/settings/api.

  2. Create an app. Set Authorization Callback Domain to localhost.

  3. Note your Client ID and Client Secret (keep the secret private).

2. Install

git clone <your-repo-url> strava-mcp-server
cd strava-mcp-server
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

3. Configure credentials

cp .env.example .env
# edit .env: set STRAVA_CLIENT_ID and STRAVA_CLIENT_SECRET

4. Authorize (one time) to get a refresh token

python scripts/get_token.py

This opens your browser, catches the redirect on localhost, exchanges the code, and prints a STRAVA_REFRESH_TOKEN=... line. Paste it into .env.

5. Register the server with Claude

Claude Code — copy mcp.example.json to .mcp.json in the repo root (adjust the python path to your venv, e.g. .venv/bin/python, if needed), then start Claude Code from this directory. Approve the server when prompted.

Claude Desktop — add the strava block from mcp.example.json to your claude_desktop_config.json under mcpServers, using absolute paths:

{
  "mcpServers": {
    "strava": {
      "command": "/absolute/path/to/strava-mcp-server/.venv/bin/python",
      "args": ["-m", "strava_mcp.server"],
      "cwd": "/absolute/path/to/strava-mcp-server"
    }
  }
}

Restart Claude Desktop. You should see the Strava tools appear.

6. Sanity check

python -m strava_mcp.server   # should start and wait on stdio; Ctrl-C to exit

Security model

  • No secrets in git. .env, .strava_tokens.json, and key files are gitignored. Only .env.example is tracked.

  • Read-only scope. The app requests read, activity:read_all, and profile:read_all — no write scopes. The server issues only GET requests to data endpoints.

  • Token hygiene. Access tokens (6-hour lifetime) are refreshed automatically from your refresh token. Strava rotates the refresh token on each exchange; the server persists the current one to .strava_tokens.json (chmod 600, gitignored).

  • Rate limits. Honors Strava's 200 req / 15 min and 2,000 / day limits with automatic backoff on HTTP 429.

  • Revoking access. Remove the app anytime at https://www.strava.com/settings/apps. Delete .strava_tokens.json and .env to purge local credentials.

Publish to GitHub

From the repo root (secrets are already gitignored, so this is safe):

The GitHub repo already exists at https://github.com/esowder22/strava-mcp-server, so just wire up the remote and push:

git init
git add .
git status                     # confirm .env / .strava_tokens.json are NOT listed
git commit -m "Initial commit: read-only Strava MCP server"
git branch -M main
git remote add origin git@github.com:esowder22/strava-mcp-server.git
git push -u origin main

Prefer HTTPS over SSH? Use git remote add origin https://github.com/esowder22/strava-mcp-server.git instead.

If the GitHub repo was created with a README/license and the push is rejected, run git pull --rebase origin main once, then push again. Keep the repo private — even though no secrets are committed, there's no reason to make it public.

Compatibility note

Written for the current mcp 2.x SDK (where FastMCP is MCPServer), with a fallback import so it also runs on mcp 1.x. No code change needed either way.

License

MIT — see LICENSE.

Available Tools

6 tools
get_activityB

Return full detail for one activity (splits, pace, HR, power, elevation, segments).

Inputs: activity_id (required).

get_activity_streamsA

Return time-series streams for an activity for detailed pace/HR/elevation analysis.

Args: activity_id: The activity to inspect. keys: Stream types to fetch. Defaults to time, distance, heartrate, velocity_smooth, altitude.

Inputs: activity_id (required), keys.

get_athleteA

Return the authenticated athlete's profile (name, location, weight, FTP if set).

Inputs: no named parameters.

get_athlete_zonesA

Return the athlete's configured heart-rate and power zones.

Inputs: no named parameters.

get_statsA

Return lifetime, year-to-date, and recent (last 4 weeks) totals for the athlete.

Covers run, ride, and swim distance/time/elevation. Useful for tracking load and progress over time.

Inputs: no named parameters.

list_activitiesA

List the athlete's activities, most recent first.

Args: per_page: Activities per page (1-200, default 30). page: Page number (default 1). before: Optional Unix timestamp; only activities before this time. after: Optional Unix timestamp; only activities after this time.

Inputs: page, after, before, per_page.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool targets a clearly distinct resource or granularity: athlete profile, aggregate stats, activity list, activity detail, time-series streams, and zones. The only close pair, get_activity and get_activity_streams, is cleanly separated by summary detail vs. raw time-series data.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun snake_case pattern, with five using get_ and one using list_activities. The lone list_ is still a standard retrieval verb, so the naming stays predictable and coherent.

    Tool Count5/5

    Six tools is a well-scoped size for a read-only Strava analytics server. Each tool covers a distinct part of the activity/athlete data surface without unnecessary duplication or bloat.

    Completeness5/5

    For the apparent purpose of retrieving athlete and activity data, the surface is complete: profile, aggregate stats, activity listing, detailed activity, streams, and zones. There are no dead ends for common queries like 'how fast was my last ride?' or 'what are my power zones?'

    Related MCP Connectors

    Related MCP Servers