io.github.davidmosiah/strava-mcp
Privacy-first MCP server for Strava activities, streams, routes and training.
Open source Open in the app JSON README (API)
About
Privacy-first MCP server for Strava activities, streams, routes and training.
Details
- Kind
- MCP servers
- Topic
- No topic detected
- Publisher
- davidmosiah
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.4.6
- Stars
- 3
- Last push
- 2026-08-29T10:28:53Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:02:41
- Updated
- 2026-08-29 03:02:41
- Origin id
io.github.davidmosiah/strava-mcp
README
<!-- delx-wellness header v2 -->
<h1 align="center">Strava MCP</h1>
<div align="center">
<img src="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 — locally.<br>
Local-first MCP server — <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="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` — preconfigures this connector and the other 8 in a dedicated Hermes profile.
>
> Or wire it standalone into Claude Desktop / Cursor / ChatGPT Desktop — 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](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](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.