Strava MCP Broker
README.md
# Strava MCP Broker
An HTTP broker that exposes the [`r-huijts/strava-mcp`](https://github.com/r-huijts/strava-mcp) server over **MCP Streamable HTTP**, with per-user Strava OAuth2. Each user brings their own Strava API credentials — no shared app secrets needed.
## Quick Start (Hosted Version)
A public instance is running at **[strava-mcp.julian-bruegger.ch](https://strava-mcp.julian-bruegger.ch)**. No setup required.
1. Create a Strava API app at [strava.com/settings/api](https://www.strava.com/settings/api)
- Set **Authorization Callback Domain** to `strava-mcp.julian-bruegger.ch`
2. Visit [strava-mcp.julian-bruegger.ch](https://strava-mcp.julian-bruegger.ch)
3. Enter your Strava **Client ID** and **Client Secret**, then click **Connect with Strava**
4. Authorize on Strava — you'll receive your personal MCP endpoint URL
5. Add the endpoint to Claude:
- **Claude.ai**: Settings → Integrations → Add MCP server → paste the URL
- **Claude Desktop**: Add to your `claude_desktop_config.json` (see [below](#connect-to-claude))
6. Manage your sessions anytime at [strava-mcp.julian-bruegger.ch/dashboard](https://strava-mcp.julian-bruegger.ch/dashboard)
---
## Self-Hosted Version
Host your own instance with Docker and Cloudflare Tunnel.
### Architecture
```
Claude.ai / Claude Desktop
│ HTTPS (MCP Streamable HTTP)
▼
Cloudflare Tunnel
│
▼
Docker: strava-mcp-broker (Express server, port 3000)
│ stdio JSON-RPC
▼
Docker: @r-huijts/strava-mcp-server (child process per session)
│ HTTPS
▼
Strava API v3
```
### Prerequisites
- A server with Docker + Docker Compose (e.g. Proxmox, VPS, Raspberry Pi)
- A domain managed by Cloudflare (free plan is fine)
- A free Cloudflare Zero Trust account ([one.dash.cloudflare.com](https://one.dash.cloudflare.com))
### Step 1 — Set Up Cloudflare Tunnel
1. Log in to [one.dash.cloudflare.com](https://one.dash.cloudflare.com)
2. Go to **Networks → Tunnels → Create a tunnel**
3. Choose **Cloudflared** as the connector type
4. Name your tunnel (e.g. `strava-mcp`)
5. On the "Install connector" page, choose **Docker** — copy the tunnel token
6. In **Public Hostname**, add a route:
- **Subdomain**: `strava-mcp`
- **Domain**: `yourdomain.com`
- **Service**: `http://strava-mcp:3000` (Docker service name on the internal network)
7. Save the tunnel
### Step 2 — Configure and Deploy
```bash
git clone https://github.com/julianbruegger/strava-mcp-broker
cd strava-mcp-broker
cp env.example .env
```
Edit `.env`:
```env
PUBLIC_URL=https://strava-mcp.yourdomain.com
CLOUDFLARE_TUNNEL_TOKEN=eyJhIjoiM... # from Step 1
SESSION_SECRET=<run: openssl rand -hex 32>
```
Deploy:
```bash
docker compose up -d --build
```
Check logs:
```bash
docker compose logs -f
```
You should see:
```
strava-mcp-broker | Strava MCP broker running on http://0.0.0.0:3000
strava-mcp-broker | Public URL: https://strava-mcp.yourdomain.com
strava-mcp-tunnel | Registered tunnel connection
```
### Step 3 — Connect Your Strava Account
1. Go to [strava.com/settings/api](https://www.strava.com/settings/api) and create an app
- Set **Authorization Callback Domain** to your tunnel domain (e.g. `strava-mcp.yourdomain.com`)
2. Open your broker URL in a browser
3. Enter your **Client ID** and **Client Secret**, then click **Connect with Strava**
4. Authorize on Strava — you'll receive your personal MCP endpoint URL
---
## Connect to Claude
### Option A — Claude.ai (recommended)
Go to **Settings → Integrations → Add MCP server** and paste your endpoint URL:
```
https://strava-mcp.yourdomain.com/mcp?session=YOUR_SESSION_TOKEN
```
### Option B — Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"strava": {
"command": "npx",
"args": [
"mcp-remote",
"https://strava-mcp.yourdomain.com/mcp?session=YOUR_SESSION_TOKEN"
]
}
}
}
```
Restart Claude Desktop. You'll see the Strava tools available.
---
## Available Tools (25+)
| Category | Tools |
|----------|-------|
| **Athlete** | `get-athlete`, `get-athlete-stats`, `get-athlete-zones` |
| **Activities** | `get-activities`, `get-activity`, `get-activity-laps`, `get-activity-streams`, `get-activity-photos`, `get-activity-comments`, `get-activity-kudoers`, `create-activity`, `update-activity`, `delete-activity` |
| **Routes** | `get-routes`, `get-route`, `list-athlete-routes`, `export-route-gpx`, `export-route-tcx` |
| **Segments** | `get-starred-segments`, `get-segment`, `get-segment-effort`, `explore-segments`, `star-segment` |
| **Clubs** | `get-clubs`, `get-club`, `get-club-activities` |
| **Gear** | `get-gear` |
| **Connection** | `connect-strava`, `disconnect-strava`, `check-connection` |
See [SKILL.md](SKILL.md) for detailed tool descriptions and usage guidelines.
---
## Dashboard
Each user gets a dashboard at `/dashboard` to manage their sessions:
- View all connected sessions
- See MCP endpoint URLs
- Delete individual sessions
- Delete all data at once
The dashboard is protected by a signed cookie set during Strava OAuth — no extra login needed.
---
## Maintenance (Self-Hosted)
### Update to latest strava-mcp-server version
```bash
docker compose build --no-cache
docker compose up -d
```
### Backup tokens
```bash
docker cp strava-mcp-broker:/data/tokens.db ./tokens-backup.db
```
---
## Security Notes
- Each user provides their own Strava API credentials — the broker stores no shared secrets
- Session tokens are random 256-bit hex strings — treat them like passwords
- Tokens are stored in SQLite at `/data/tokens.db` (mounted volume) — back it up
- Access tokens are refreshed automatically (Strava tokens expire every 6 hours)
- The `/mcp` endpoint is rate-limited (60 req/min per IP) and requires a valid session token
- Dashboard auth uses HMAC-signed cookies (30-day expiry, HttpOnly, SameSite)
- Cloudflare Tunnel handles TLS — no certificates needed on the server
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues