strava-mcp
Personal MCP server for Strava with OAuth authentication, beautiful dashboard, and personal MCP URLs for AI assistants
π SportsMCP β Strava for Any AI Agent
Production-ready MCP server for Strava β works with Claude Desktop, Cursor, Windsurf, Cline, Continue.dev, Poke, and any MCP-compatible AI agent.
A complete Model Context Protocol server that gives any AI assistant secure, read-only access to your personal Strava fitness data. Deploy once to Cloudflare Workers, authenticate with Strava, and paste your personal MCP URL into whichever AI tools you use.
Compatible with Strava. SportsMCP is not affiliated with, endorsed, or sponsored by Strava.
β¨ Features
- π€ Works with any MCP client β Claude Desktop, Cursor, Windsurf, Cline, Continue.dev, Poke, and more
- π Secure OAuth β Standard Strava OAuth 2.0, per-user token isolation
- π 21 MCP Tools β Activities, laps, kudos, comments, segments, segment efforts, routes, gear, clubs, athlete zones, and more
- π Optional Webhooks β Real-time Poke notifications when workouts complete (per-user keys)
- π Auto Token Refresh β Tokens renew automatically before expiry
- π¨ Dashboard β Web UI with one-click config snippets for every major AI agent
- β‘ Edge Performance β Cloudflare Workers global network, <50ms response times
- π° Free Tier β 100k requests/day at zero cost
- π‘οΈ Compliance β Full Strava API agreement compliance, deauth cleanup within 48h
π Quick Start
Note: Deploying to Cloudflare requires some terminal commands, but we've made it as simple as possible!
π Option A: Deploy Button + Setup Script (Easiest!)Click a button, then run one command
Best for users who prefer clicking buttons over typing commands.
β οΈ Make sure to copy/duplicate the Repo First β οΈ
Step 1: Click Deploy to Cloudflare
This will:
- Deploy it to your Cloudflare account
- Give you a worker URL
Step 2: Finish Configuration
After deployment, you need to configure secrets and webhooks:
Open Terminal (Mac: Cmd+Space, type "Terminal" | Windows: search "PowerShell")
Clone YOUR fork and run setup:
# Replace YOUR-USERNAME with your GitHub username git clone https://github.com/YOUR-USERNAME/strava-mcp.git cd strava-mcp npm install node scripts/setup.jsAnswer the prompts:
- Strava Client ID (get from strava.com/settings/api)
- Strava Client Secret
- Poke API (or other AI/Chat App) key for webhooks (optional)
Done! Visit your worker URL and authenticate with Strava.
Copy & paste 5 commands, answer a few questions, done!
Best for users comfortable with terminal commands.
This automated script handles everything: forking, database creation, configuration, secrets, webhooks, and deployment.
Step 1: Open Terminal
- Mac: Press Cmd+Space, type "Terminal", press Enter
- Windows: Search "Command Prompt" or "PowerShell"
Step 2: Copy & Paste These Commands
Paste these commands one at a time (press Enter after each):
# Download the project
git clone https://github.com/gabeperez/strava-mcp.git
# Go into the folder
cd strava-mcp
# Install dependencies (takes ~30 seconds)
npm install
# Login to Cloudflare (opens browser - just click "Allow")
wrangler login
# Run automated setup (asks you a few questions, then does everything!)
node scripts/setup.js
Step 3: Answer the Prompts
The script will ask you for:
- Strava Client ID - Get from strava.com/settings/api
- Strava Client Secret - Same page as above
- Set up webhooks? - Type "y" for push notifications (optional)
- Poke API Key - If you said yes to webhooks, get from poke.com/settings/advanced
Step 4: Done! π
The script automatically:
- β Creates your database (KV namespace)
- β Updates all configuration files
- β Sets your secrets securely
- β Sets up webhooks (if you chose yes)
- β Deploys to Cloudflare
- β Gives you your worker URL
Step 5: Visit Your Dashboard
- Open the URL the script gave you (looks like
https://sportsmcp.yourname.workers.dev) - Click "Authenticate with Strava"
- You'll see your beautiful dashboard with:
- π Recent activities
- π Performance stats
- π Personal MCP URL for AI assistants
- π Webhook status (if enabled)
Step 6: Connect to your AI agent
Copy your personal MCP URL from the dashboard and add it to your preferred AI agent:
π€ Connecting to AI Agents
SportsMCP uses the standard Model Context Protocol, so it works with any MCP-compatible client. Your personal URL looks like:
https://your-worker.workers.dev/mcp?token=YOUR_TOKEN
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"sportsmcp": {
"url": "https://your-worker.workers.dev/mcp?token=YOUR_TOKEN"
}
}
}
Restart Claude Desktop after saving.
Cursor
Go to Settings β Cursor Settings β MCP and add:
{
"mcpServers": {
"sportsmcp": {
"url": "https://your-worker.workers.dev/mcp?token=YOUR_TOKEN"
}
}
}
Windsurf
Go to Settings β Cascade β MCP Servers and add the same JSON block as Cursor above.
Cline (VS Code)
Open Cline β MCP Servers β Edit Config and add the same JSON block.
Continue.dev
Add to ~/.continue/config.json:
{
"mcpServers": [
{
"name": "sportsmcp",
"transport": {
"type": "streamable-http",
"url": "https://your-worker.workers.dev/mcp?token=YOUR_TOKEN"
}
}
]
}
Poke
Go to Settings β Integrations β Add MCP Server and paste your MCP URL directly.
Any other MCP client
Two transports are available:
- Streamable HTTP (recommended):
POST /mcp?token=YOUR_TOKEN - HTTP+SSE (legacy, e.g. older Claude Desktop):
GET /sse?token=YOUR_TOKEN+POST /messages?token=YOUR_TOKEN
That's it! Ask your AI: "Show me my recent Strava workouts" π
π οΈ Advanced: Manual Step-by-Step SetupFor developers who want full control
If you prefer to configure everything manually instead of using the automated script:
Prerequisites:
- Node.js 18+ installed (download here)
- Cloudflare account (free) - sign up
- Strava API app - create one
Commands to run:
# 1. Download and install
git clone https://github.com/gabeperez/strava-mcp.git
cd strava-mcp
npm install
# 2. Login to Cloudflare (opens browser)
wrangler login
# 3. Create database (KV namespace)
wrangler kv:namespace create STRAVA_SESSIONS
# Copy the "id" from output and paste into wrangler.jsonc
# 4. Set your Strava API credentials
wrangler secret put STRAVA_CLIENT_ID
# Paste your Client ID when prompted
wrangler secret put STRAVA_CLIENT_SECRET
# Paste your Client Secret when prompted
# 5. Deploy to Cloudflare
npm run deploy
# 6. Visit your worker URL to authenticate
open https://your-worker-name.your-subdomain.workers.dev/auth
Optional: Set up webhooks
wrangler secret put STRAVA_WEBHOOK_VERIFY_TOKEN
wrangler secret put POKE_API_KEY
See README_DEPLOY.md for detailed manual setup guide.
π Real-time Webhooks (Optional)
β οΈ Personal Use Only: Webhooks currently send notifications to a single Poke API key. Only enable if you're the sole user of this deployment. Multi-user webhook support coming soon.
Get instant push notifications via Poke when you finish workouts!
π± Click to see webhook notification exampleπ New Strava Workout!
**Morning Run**
Type: Run
Date: Oct 29, 2025 7:30 AM
Distance: 10.5 km
Duration: 52 minutes
Pace: 4:57 min/km
Elevation: 120m
Avg HR: 145 bpm
π 2 PRs!
Sent instantly to your phone via iMessage/SMS when you complete an activity!
Quick Webhook Setup
# 1. Set Poke API key (get from https://poke.com/settings/advanced)
wrangler secret put POKE_API_KEY
# 2. Set webhook verification token
wrangler secret put STRAVA_WEBHOOK_VERIFY_TOKEN
# Enter: STRAVA_MCP_WEBHOOK
# 3. Test endpoint
node scripts/manage-webhook.js test
# 4. Create subscription
STRAVA_CLIENT_ID=xxx STRAVA_CLIENT_SECRET=xxx \
node scripts/manage-webhook.js create
# 5. Monitor events
wrangler tail
See WEBHOOK_SETUP.md for complete instructions
π Available MCP Tools (21 Total)
Ask your AI assistant natural language questions, and these tools will be called automatically:
Activities
| Tool | Example Query |
|---|---|
get-recent-activities |
"Show me my last 5 workouts" |
get-activity-details |
"Get details for my last ride" |
get-activity-streams |
"Show me heart rate data from my last run" |
get-activity-laps |
"What were my lap splits?" |
get-activity-kudos |
"Who gave me kudos on my run?" |
get-activity-comments |
"What comments did I get?" |
Athlete
| Tool | Example Query |
|---|---|
get-athlete-profile |
"What's my Strava profile info?" |
get-athlete-stats |
"What are my cycling stats this year?" |
get-athlete-zones |
"What are my heart rate training zones?" |
get-athlete-clubs |
"What Strava clubs am I in?" |
get-athlete-routes |
"List my saved routes" |
Segments
| Tool | Example Query |
|---|---|
get-starred-segments |
"What segments have I starred?" |
explore-segments |
"Find climbing segments near San Francisco" |
get-segment |
"Tell me about segment 1234" |
get-segment-efforts |
"What are my best efforts on this segment?" |
get-segment-effort |
"Get details for segment effort 5678" |
Gear & Social
| Tool | Example Query |
|---|---|
get-gear |
"How many miles are on my running shoes?" |
get-club |
"Tell me about my cycling club" |
get-route |
"Get details for my weekend route" |
authenticate-strava |
"How do I connect my Strava account?" |
welcome-strava-mcp |
"How do I get started?" |
π Endpoints
| Endpoint | Purpose |
|---|---|
/ |
Landing page & documentation |
/auth |
Start OAuth flow |
/dashboard?token=xxx |
Personal dashboard with stats |
/mcp |
MCP server endpoint (for AI assistants) |
/webhook |
Strava webhook receiver (optional) |
/test-poke |
Test Poke integration |
π― Usage Examples
With Poke
- Add MCP server in Poke settings
- Use URL:
https://your-worker-url.workers.dev/mcp - Ask: "What was my pace on yesterday's run?"
With Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"strava": {
"url": "https://your-worker-url.workers.dev/mcp"
}
}
}
Natural Language Queries
- "Show me my recent Strava activities"
- "What was my heart rate during my last run?"
- "Get power data from yesterday's bike ride"
- "Find challenging segments near Boulder"
- "What are my all-time cycling stats?"
π Security Features
- Device Fingerprinting - Automatic authentication by browser
- Token Refresh - Seamless renewal before expiration
- Per-user Isolation - Complete data separation
- Secure Storage - KV encryption for tokens
- CSRF Protection - State validation in OAuth flow
- Rate Limiting - Respects Strava API quotas
ποΈ Architecture
βββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββ
β AI Assistant βββββΆβ Cloudflare Worker βββββΆβ Strava API β
β (Poke/Claude) β β β β β
β β β β’ MCP Server β β β’ Activities β
β Natural Languageβ β β’ OAuth Handler β β β’ Segments β
β Queries β β β’ Device Auth β β β’ Routes β
β β β β’ Token Manager β β β’ Stats β
β β β β’ Webhook Handler β β β
βββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββ βββββββββββββββββββ
β Cloudflare KV β β Poke API β
β β’ Sessions β β β’ Push Notify β
β β’ OAuth Tokens β β β’ iMessage/SMS β
β β’ Activity Data β βββββββββββββββββββ
ββββββββββββββββββββ
π Documentation
- README_DEPLOY.md - Step-by-step deployment (5 minutes)
- WEBHOOK_SETUP.md - Complete webhook guide
- WEBHOOK_QUICKSTART.md - Quick webhook reference
- WARP.md - Development & architecture details
- PUBLISHING_CHECKLIST.md - Template publishing guide
π οΈ Tech Stack
- Runtime: Cloudflare Workers (V8 isolates)
- Framework: Hono (lightweight web framework)
- Storage: Cloudflare KV (sessions & tokens)
- Protocol: Model Context Protocol (MCP)
- Auth: Strava OAuth 2.0
- Notifications: Poke API (optional)
π° Pricing
100% Free! Runs on Cloudflare's generous free tier:
- Workers: 100,000 requests/day
- KV Storage: 100,000 reads/day, 1,000 writes/day
- Bandwidth: Unlimited on free tier
Perfect for personal use. No credit card required.
π§ Development
Local Testing
# Install dependencies
npm install
# Start local server
wrangler dev
# Visit http://localhost:8787
Run Tests
npm test
Environment Variables
See .env.example for all configuration options.
π Troubleshooting
Authentication Issues"Authentication Required" error
- Visit
/authto re-authenticate - Make sure you're using the same browser/device
- Check
/statusendpoint to verify session
"Invalid Callback Domain"
- Verify Strava app callback domain matches worker URL exactly
- Don't include protocol (http://) or path (/callback)
Not receiving webhook events
- Run
node scripts/manage-webhook.js viewto check subscription - Monitor logs with
wrangler tail - Verify athlete is authenticated (visit
/dashboard) - Check Strava app has correct OAuth scopes
Poke notifications not working
- Verify
POKE_API_KEYis set:wrangler secret list - Test manually:
curl -X POST https://your-worker-url.workers.dev/test-poke - Check logs for Poke API errors
"KV namespace not found"
- Create namespace:
wrangler kv:namespace create STRAVA_SESSIONS - Update ID in
wrangler.jsonc
"Deployment failed"
- Verify logged in:
wrangler whoami - Check syntax in
wrangler.jsonc - Ensure all secrets are set
πΊοΈ Roadmap
Coming Soon
- Multi-user Webhook Support - Per-user Poke API keys and notification routing
- Public sportsmcp.com Service - Hosted version for non-technical users
- More Notification Channels - Discord, Slack, email, etc.
- Activity Analytics - Trends, insights, and training load tracking
- Custom Webhook Filters - Choose which activities trigger notifications
- Web Dashboard Enhancements - More stats, charts, and visualizations
Interested in contributing to any of these? Open a discussion!
π€ Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
π License
MIT License - see LICENSE file for details.
π Credits
- Built with Hono
- Powered by Cloudflare Workers
- MCP by Anthropic
- Notifications via Poke
- Inspired by the Strava community πββοΈπ΄ββοΈ
β Star History
If this project helped you, consider giving it a star!
Made with β€οΈ for athletes who love data
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found