strava-mcp

mcp
SUMMARY

Personal MCP server for Strava with OAuth authentication, beautiful dashboard, and personal MCP URLs for AI assistants

README.md

πŸƒ 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.

Deploy to Cloudflare Workers

Cloudflare Workers
GitHub
MCP Protocol
Compatible with Strava
License: MIT

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

Deploy to Cloudflare Workers

This will:

  1. Deploy it to your Cloudflare account
  2. Give you a worker URL

Step 2: Finish Configuration

After deployment, you need to configure secrets and webhooks:

  1. Open Terminal (Mac: Cmd+Space, type "Terminal" | Windows: search "PowerShell")

  2. 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.js
    
  3. Answer the prompts:

  4. Done! Visit your worker URL and authenticate with Strava.

⚑ Option B: Fully Automated Setup (One Script Does Everything!)

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:

  1. Strava Client ID - Get from strava.com/settings/api
  2. Strava Client Secret - Same page as above
  3. Set up webhooks? - Type "y" for push notifications (optional)
  4. 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

  1. Open the URL the script gave you (looks like https://sportsmcp.yourname.workers.dev)
  2. Click "Authenticate with Strava"
  3. 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 Setup

For developers who want full control

If you prefer to configure everything manually instead of using the automated script:

Prerequisites:

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

  1. Add MCP server in Poke settings
  2. Use URL: https://your-worker-url.workers.dev/mcp
  3. 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

πŸ› οΈ 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 /auth to re-authenticate
  • Make sure you're using the same browser/device
  • Check /status endpoint to verify session

"Invalid Callback Domain"

  • Verify Strava app callback domain matches worker URL exactly
  • Don't include protocol (http://) or path (/callback)
Webhook Issues

Not receiving webhook events

  • Run node scripts/manage-webhook.js view to 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_KEY is set: wrangler secret list
  • Test manually: curl -X POST https://your-worker-url.workers.dev/test-poke
  • Check logs for Poke API errors
Deployment Issues

"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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“ License

MIT License - see LICENSE file for details.

πŸ™ Credits

⭐ Star History

If this project helped you, consider giving it a star!


Made with ❀️ for athletes who love data

Report Bug Β· Request Feature Β· Discussions

Reviews (0)

No results found