# strava-mcp [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/davidmosiah/strava-mcp  
**GitHub Stars:** 3  
**npm Downloads (last month):** 112  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/strava-mcp

## Description
Privacy-first MCP server for Strava activities, streams, routes and training.

## Tools
Capabilities this server exposes over MCP:

- **strava_connection_status** — verify local setup, scopes and readiness before calling Strava
- **strava_data_inventory** — inventory supported data domains, scopes, privacy modes and recommended first calls without calling Strava APIs.
- **strava_daily_summary** — latest activity, weekly load and intensity context for today
- **strava_weekly_summary** — scorecard, comparison vs prior week, next-week training plan

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "strava-mcp": {
    "command": "npx",
    "args": ["-y","delx-wellness-hermes"]
  }
}
```

## Documentation & README

<!-- delx-wellness header v2 -->
<h1 align="center">Strava MCP</h1>

<div align="center">
  <img src="https://raw.githubusercontent.com/davidmosiah/strava-mcp/HEAD/assets/banner.png" alt="Strava MCP — Strava MCP for AI agents" width="85%" />
</div>

<h3 align="center">
  Give your AI agent your Strava activities, streams, segments and routes &mdash; locally.<br>
  Local-first MCP server &mdash; <strong>tokens never leave your machine</strong>.
</h3>

<p align="center">
  <a href="https://www.npmjs.com/package/strava-mcp-unofficial"><img src="https://img.shields.io/npm/v/strava-mcp-unofficial?style=for-the-badge&labelColor=0F172A&color=10B981&logo=npm&logoColor=white" alt="npm version" /></a>
  <a href="https://www.npmjs.com/package/strava-mcp-unofficial"><img src="https://img.shields.io/npm/dm/strava-mcp-unofficial?style=for-the-badge&labelColor=0F172A&color=0EA5A3&logo=npm&logoColor=white" alt="npm downloads" /></a>
  <a href="https://github.com/davidmosiah/strava-mcp/blob/HEAD/LICENSE"><img src="https://img.shields.io/badge/LICENSE-MIT-22C55E?style=for-the-badge&labelColor=0F172A" alt="License MIT" /></a>
  <a href="https://wellness.delx.ai/connectors/strava"><img src="https://img.shields.io/badge/SITE-wellness.delx.ai-0EA5A3?style=for-the-badge&labelColor=0F172A" alt="Site" /></a>
</p>

<p align="center">
  <a href="https://github.com/davidmosiah/strava-mcp/stargazers"><img src="https://img.shields.io/github/stars/davidmosiah/strava-mcp?style=for-the-badge&labelColor=0F172A&color=FBBF24&logo=github" alt="GitHub stars" /></a>
  <a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/BUILT_FOR-MCP-7C3AED?style=for-the-badge&labelColor=0F172A" alt="Built for MCP" /></a>
  <a href="https://github.com/davidmosiah/delx-wellness-hermes"><img src="https://img.shields.io/badge/HERMES-one--command_setup-10B981?style=for-the-badge&labelColor=0F172A" alt="Hermes one-command setup" /></a>
  <a href="https://github.com/davidmosiah/delx-wellness"><img src="https://img.shields.io/badge/Strava-FC4C02?style=for-the-badge&labelColor=0F172A&logoColor=white&logo=strava&logoColor=white" alt="Strava" /></a>
</p>

> ⚡ **One-command install** with [Delx Wellness for Hermes](https://github.com/davidmosiah/delx-wellness-hermes):
> `npx -y delx-wellness-hermes setup` &mdash; preconfigures this connector and the other 8 in a dedicated Hermes profile.
>
> Or wire it standalone into Claude Desktop / Cursor / ChatGPT Desktop &mdash; see the install section below.

---

## HTTP (v2 stateless)

Default is **stdio**. Optional Streamable HTTP — no session id, JSON responses, loopback only:

```bash
npx -y strava-mcp-unofficial --http
# GET  http://127.0.0.1:3000/health
# POST http://127.0.0.1:3000/mcp   (sessionless)
```

Env: `STRAVA_MCP_HOST`, `STRAVA_MCP_PORT`, `STRAVA_MCP_TRANSPORT=http`.


<!-- /delx-wellness header v2 -->

**Local-first MCP server that connects AI agents to your Strava activities, routes, streams and training context.**

> **Unofficial project.** Not affiliated with, endorsed by or supported by Strava, Inc. Strava is a trademark of its respective owner. Use this only with your own Strava account and in line with Strava's API agreement.

Built by [David Mosiah](https://github.com/davidmosiah) for people who use Claude, Cursor, Hermes, OpenClaw or other MCP-compatible agents to think about training, endurance and performance — without copy-pasting numbers from Strava.

Part of [Delx Wellness](https://github.com/davidmosiah/delx-wellness), a registry of local-first wellness MCP connectors.

> If this connector helps your agent workflow, please star the repo. Stars make the project easier for other AI builders to discover and help Delx keep shipping local-first wellness infrastructure.

## Why this exists

Strava holds the long memory of your training — every ride, run, swim, segment, route and stream. But it lives behind an OAuth API with strict rate limits (200 req/15min, 2k/day per app) and GPS data that's privacy-sensitive by default.

This package does the OAuth dance locally, throttles under Strava's per-app limits, redacts GPS lat/lng unless you explicitly opt in, and exposes Strava through the Model Context Protocol. Any MCP-compatible agent gets your training context with one config snippet. Tokens never leave your machine.

## Quickstart

From zero to your first agent call in about a minute. You only need a Strava app ([create one here](https://www.strava.com/settings/api)) with redirect URI `http://127.0.0.1:3000/callback`.

**1. Paste your app's client id + secret** (interactive, stored at `~/.strava-mcp/config.json` with `0600`):

```bash
npx -y strava-mcp-unofficial setup
```

**2. Authorize Strava.** `auth` opens your browser; `--no-open` prints the URL so you can paste it yourself (handy on a headless box). Tokens are saved locally — the command never prints them:

```console
$ npx -y strava-mcp-unofficial auth --no-open
Strava MCP · Authorization

Open this URL manually:
  https://www.strava.com/oauth/authorize?client_id=12345&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Fcallback&response_type=code&approval_prompt=auto&scope=read%2Cactivity%3Aread_all%2Cprofile%3Aread_all&state=aa38f29b

Steps
  1. Approve access in the browser tab that opens.
  2. Strava will redirect to the local callback.
  3. Tokens are saved locally; this command never prints them.

Waiting for callback...
```

**3. Verify you're ready** — `doctor` confirms scopes and setup without calling Strava:

```console
$ npx -y strava-mcp-unofficial doctor
Strava MCP · Doctor
Status: READY ✓

Checks
  ✓  Node.js >=20
  ✓  Env vars
  ✓  Local config
  ✓  Automatic auth redirect
  ✓  Token file
  ✓  Token permissions
  ✓  Refresh token
  ✓  OAuth scopes
  ·  Privacy mode
  ·  Cache

Next steps
  1. Ready. Add this MCP server to your agent and start with strava_daily_summary.
```

If `OAuth scopes` shows a `✗`, re-run `auth` and approve `activity:read_all profile:read_all read`.

**4. Make a first call — no live account required.** Ask your agent to run `strava_demo`. It returns realistic, synthetic payloads (tagged `is_demo: true`) so you can wire prompts before connecting real data:

```text
> Call strava_demo and summarize my week.

# Strava Demo

- **is_demo**: true
- **recent_sessions**: 3
- **load_classification**: moderate
- **primary_signal**: Recent Strava load is manageable; use intent and consistency as the main lever.
- **recommended_handoff**: exercise_catalog_recommend_session
```

Call it with `response_format: "json"` for the full shapes. The `sample` block mirrors `strava_daily_summary`, `strava_training_context` and `strava_list_activities` key-for-key — `npm run test:demo-contract` runs the real builders over `fixtures/strava-activities.mjs` and fails the build if the demo ever invents a field or omits one. Swap `strava_demo` for the real tool and the same shape arrives filled with your Strava data.

**5. Wire it into your MCP client:**

```json
{
  "mcpServers": {
    "strava": {
      "command": "npx",
      "args": ["-y", "strava-mcp-unofficial"]
    }
  }
}
```

For Claude Desktop, run `setup --client claude` and the snippet is written for you. For Hermes, see [Hermes / remote setup](#hermes--remote-setup) below.

## Try it with your agent

Three things to ask first:

```text
Use strava_connection_status to check setup, then run strava_daily_summary.
Tell me what my training context looks like in 5 lines.
```

```text
Call strava_weekly_summary with response_format=json. Find my biggest
load/intensity bottleneck and give me a next-week endurance plan.
```

```text
Use the strava_activity_stream_investigator prompt for activity_id=<id>.
Don't expose GPS unless I explicitly ask for it.
```

## Data availability

This package uses the official Strava API v3. When this README says `raw`, it means the upstream Strava JSON for a supported endpoint — not continuous device telemetry.

| Data | Available | Notes |
|---|:---:|---|
| Activities (runs, rides, swims, walks, workouts) | ✓ | All recorded activities |
| Activity details + zones + splits | ✓ | HR, power, cadence, elevation, gear |
| Activity streams (HR / cadence / watts / altitude) | ✓ | Per-second samples for the activity |
| GPS lat/lng streams | opt-in | Hidden by default; requires `include_gps=true` or `raw` mode |
| Athlete profile + zones + aggregate stats | ✓ | Authenticated athlete |
| Routes + clubs + gear | ✓ | Route geometry redacted in summary/structured modes |
| Live device telemetry / continuous HR | — | Not exposed by Strava's public API |

## Tools

**Start with these:**

- `strava_connection_status` — verify local setup, scopes and readiness before calling Strava
- `strava_data_inventory` — inventory supported data domains, scopes, privacy modes and recommended first calls without calling Strava APIs.
- `strava_daily_summary` — latest activity, weekly load and intensity context for today
- `strava_weekly_summary` — scorecard, comparison vs prior week, next-week training plan

**Auth & diagnostics**

- `strava_capabilities`, `strava_agent_manifest`, `strava_privacy_audit`, `strava_cache_status`
- `strava_get_auth_url`, `strava_exchange_code`, `strava_revoke_access`

**Athlete & training**

- `strava_get_athlete`, `strava_get_zones`, `strava_get_athlete_stats`

**Activities & streams**

- `strava_list_activities`, `strava_get_activity`, `strava_get_activity_zones`
- `strava_activity_series`, `strava_get_activity_streams` — GPS lat/lng requires `include_gps=true` or `raw` mode

**Routes & context**

- `strava_list_routes`, `strava_get_route`, `strava_list_clubs`, `strava_get_gear`

## Prompts

- `strava_daily_training_director` — practical daily training brief
- `strava_weekly_endurance_review` — week comparison + next-week endurance plan
- `strava_activity_stream_investigator` — investigate one activity using streams (GPS-aware)

Each accepts `timezone` (IANA, default `UTC`).

## Resources

- `strava://capabilities`, `strava://agent-manifest`
- `strava://athlete`
- `strava://latest/activity`
- `strava://summary/daily`, `strava://summary/weekly`

## Privacy & security

- OAuth tokens are stored in `~/.strava-mcp/tokens.json` with `0600` permissions and are never returned by tools.
- Write/upload scopes are **not** requested by default — read-only by design.
- GPS lat/lng and route geometry are recursively removed in `summary` and `structured` modes, and only included with explicit `include_gps=true` for stream calls or `raw` mode.
- Structured mode otherwise preserves complete upstream physiological records and future Strava fields.
- Activity `after` / `before` filters retain instant semantics when converted from timezone-aware ISO date-times to Strava epoch seconds; invalid ranges fail before HTTP.
- Route geometry is also redacted unless raw mode is explicitly requested.
- The MCP client never sees access or refresh tokens.
- This is **not medical advice**. The server exposes user-authorized data for personal AI workflows, not diagnosis or training prescription.

## Configuration

`setup` writes most of these into `~/.strava-mcp/config.json` (`0600`). Manual env override is supported:

```bash
STRAVA_CLIENT_ID=…
STRAVA_CLIENT_SECRET=…
STRAVA_REDIRECT_URI=http://127.0.0.1:3000/callback

# Optional
STRAVA_SCOPES="read activity:read_all profile:read_all"
STRAVA_PRIVACY_MODE=structured        # summary | structured | raw
STRAVA_CACHE=sqlite                   # optional read-through cache
```

## Hermes / remote setup

```bash
npx -y strava-mcp-unofficial setup --client hermes --no-auth
npx -y strava-mcp-unofficial auth                       # run locally if browser auth is needed
npx -y strava-mcp-unofficial doctor --client hermes
hermes mcp test strava
```

Hermes commonly exposes Strava tools with a prefix:

- `mcp_strava_strava_agent_manifest`
- `mcp_strava_strava_connection_status`
- `mcp_strava_strava_daily_summary`
- `mcp_strava_strava_weekly_summary`
- `mcp_strava_strava_get_activity_streams`

After Hermes config changes, use `/reload-mcp` or `hermes mcp test strava`. Don't restart the gateway for normal data access.

If browser OAuth has to happen on a different machine than Hermes, run `auth` locally and copy `~/.strava-mcp/tokens.json` to the server with `chmod 600`. The token must include `activity:read_all profile:read_all read` for activity history and streams.

## Requirements

- Node.js 20+
- A Strava app with redirect URI `http://127.0.0.1:3000/callback`

Why these scopes:

- `read` — public profile, routes and public Strava resources
- `activity:read_all` — your activities, including private activities visible to your app
- `profile:read_all` — fuller authenticated athlete profile fields

No write scope is requested by default.

## Development

```bash
git clone https://github.com/davidmosiah/strava-mcp.git
cd strava-mcp
npm install
npm test
npm run build
```

Test with MCP Inspector:

```bash
npx @modelcontextprotocol/inspector node dist/index.js
```

## Links

- npm: <https://www.npmjs.com/package/strava-mcp-unofficial>
- Docs site: <https://wellness.delx.ai/connectors/strava>
- Legacy docs: <https://stravamcp.vercel.app/>
- GitHub Pages mirror: <https://davidmosiah.github.io/strava-mcp/>
- Delx Wellness registry: <https://github.com/davidmosiah/delx-wellness>
- Connector quality standard: <https://github.com/davidmosiah/delx-wellness/blob/main/docs/connector-quality-standard.md>
- Strava API docs: <https://developers.strava.com/docs/reference/>
- Strava auth docs: <https://developers.strava.com/docs/authentication/>

<!-- delx-wellness see-also -->

## See also

The full [Delx Wellness](https://wellness.delx.ai) connector library:

| Provider | Package | Repo |
|---|---|---|
| WHOOP | [`whoop-mcp-unofficial`](https://www.npmjs.com/package/whoop-mcp-unofficial) | [whoop-mcp](https://github.com/davidmosiah/whoop-mcp) |
| Oura | [`oura-mcp-unofficial`](https://www.npmjs.com/package/oura-mcp-unofficial) | [ouramcp](https://github.com/davidmosiah/ouramcp) |
| Garmin | [`garmin-mcp-unofficial`](https://www.npmjs.com/package/garmin-mcp-unofficial) | [garminmcp](https://github.com/davidmosiah/garminmcp) |
| Strava | [`strava-mcp-unofficial`](https://www.npmjs.com/package/strava-mcp-unofficial) | [strava-mcp](https://github.com/davidmosiah/strava-mcp) |
| Fitbit | [`fitbit-mcp-unofficial`](https://www.npmjs.com/package/fitbit-mcp-unofficial) | [fitbitmcp](https://github.com/davidmosiah/fitbitmcp) |
| Withings | [`withings-mcp-unofficial`](https://www.npmjs.com/package/withings-mcp-unofficial) | [withingsmcp](https://github.com/davidmosiah/withingsmcp) |
| Apple Health | [`apple-health-mcp-unofficial`](https://www.npmjs.com/package/apple-health-mcp-unofficial) | [apple-health-mcp](https://github.com/davidmosiah/apple-health-mcp) |
| Polar | [`polar-mcp-unofficial`](https://www.npmjs.com/package/polar-mcp-unofficial) | [polarmcp](https://github.com/davidmosiah/polarmcp) |
| Nourish (nutrition) | [`wellness-nourish`](https://www.npmjs.com/package/wellness-nourish) | [wellness-nourish](https://github.com/davidmosiah/wellness-nourish) |

**One-command setup for Hermes** — preconfigures every connector above plus wellness skills + onboarding: [`delx-wellness-hermes`](https://github.com/davidmosiah/delx-wellness-hermes).

<!-- /delx-wellness see-also -->

## 📧 Contact & Support

- 📨 **support@delx.ai** — general questions, integration help, partnerships
- 🐛 **Bug reports / feature requests** — [GitHub Issues](https://github.com/davidmosiah/strava-mcp/issues)
- 🐦 **Updates** — [@delx369](https://x.com/delx369) on X
- 🌐 **Site** — [wellness.delx.ai](https://wellness.delx.ai)


## License

MIT — see [LICENSE](https://github.com/davidmosiah/strava-mcp/blob/HEAD/LICENSE).

## Disclaimer

This software is provided as-is. It is not a medical device, does not provide medical advice, and should not be used for diagnosis, treatment or training prescription. Always consult qualified professionals for medical or training concerns.

## Skill or MCP

Same package, two doors. MCP registers tools on stdio/HTTP. The [skill](https://github.com/davidmosiah/strava-mcp/blob/HEAD/skill/SKILL.md) can drive the **same** tools through the CLI when the client has no MCP:

```bash
npx -y strava-mcp-unofficial call strava_connection_status --json '{}'
```

Copy `skill/SKILL.md` into your agent skills dir.

