A Model Context Protocol (MCP) server that exposes the Strava API v3 as tools, resources, and prompts for AI agents.
Project description
🚴 Strava MCP Server
A production-ready Model Context Protocol (MCP) server that exposes the Strava API v3 as MCP-compatible tools, resources, and prompts — enabling AI agents and LLM-based applications to query your Strava training data through a standardized interface.
Built with FastMCP and the MCP Python SDK, compatible with MCP Inspector, Claude Desktop, and any MCP-compliant client.
✨ Features
- 🛠️ 25+ MCP Tools covering all major Strava API read endpoints (including athlete profile & stats)
- 💬 2 MCP Prompts for structured AI-driven training analysis
- 🔄 Automated OAuth — authentication flow via a standalone setup script with auto-rotation
- 🐳 Multi-Arch Docker — optimized builds for
linux/amd64andlinux/arm64powered byuv - 🏷️ Dynamic Versioning — versions are automatically derived from Git tags (powered by
hatch-vcs) - 🤖 Agent-First Design — includes specific instructions for LLMs on handling European date formats (DD.MM.YYYY)
- 🌐 Streamable HTTP transport for broad client compatibility (SSE)
- 🔒 Read-only — no write operations, safe to use with AI agents
- 📝 Design Decisions — documented architectural choices in
docs/DESIGN_DECISIONS.md
📋 Table of Contents
- Requirements
- Installation & Deployment
- Strava API Setup
- Connecting with MCP Clients
- MCP Primitives
- Project Structure
- Design Decisions
- CI/CD (Gitea Actions)
- Development & Testing
- Known Strava API Limitations
- Troubleshooting
Requirements
- A Strava account with API access
- A Strava API Application
- Docker (for containerized deployment) OR Python 3.10+ & uv
Installation & Deployment
Docker (Recommended)
The project includes a multi-arch Docker build (amd64/arm64).
# Clone the repository
git clone https://git.hnrx.net/hnrx/strava-mcp-server.git
cd strava-mcp-server
# Build the image locally
docker build -t strava-mcp-server:latest .
# Run the container (injecting your .env file)
docker run --rm -p 8000:8000 --env-file .env strava-mcp-server:latest
Local Python (uv)
We use uv for lightning-fast dependency management and task execution.
git clone https://git.hnrx.net/hnrx/strava-mcp-server.git
cd strava-mcp-server
# Start the MCP server
uv run server
# Run the OAuth setup script
uv run auth
Run on the fly with uvx (No git clone required)
You can run the server directly from the repository without cloning it manually by using uvx:
# Set up your .env file in the current directory first!
uvx --from git+https://git.hnrx.net/hnrx/strava-mcp-server.git server
(If you are already inside the cloned directory, you can also just run uvx --from . server)
Strava API Setup
1. Create a Strava API Application
- Go to https://www.strava.com/settings/api
- Create a new application
- Set Authorization Callback Domain to
localhost - Note your Client ID and Client Secret
2. Configure Environment
Copy the example environment file:
cp .env.example .env
Edit .env and fill in your Client ID and Secret:
STRAVA_CLIENT_ID=your_client_id_here
STRAVA_CLIENT_SECRET=your_client_secret_here
3. Authenticate (The Magic Way ✨)
The server is designed for zero-touch deployment. You can authorize it after it has started.
- Start the server (it will log a warning that the refresh token is missing, but it will boot!).
- Run the Auth Script:
- Run
uv run authin your terminal on your local machine.
- Run
- Your browser will open. Log in and authorize.
- Success: The browser will show you the exact values for your
.env(or Kubernetes Secret). The script will also automatically update your local.envfile!
Connecting with MCP Clients
The server listens on port 8000 and exposes an SSE endpoint: http://localhost:8000/mcp
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"strava": {
"url": "http://localhost:8000/mcp",
"transport": "streamable-http"
}
}
}
MCP Primitives
Tools
| Category | Tools |
|---|---|
| 🏃 Athlete | get_athlete_profile, get_athlete_stats, get_athlete_zones |
| 🚴 Activities | list_activities, get_activity_details, get_activity_laps, get_activity_zones, get_activity_streams |
| 🏘️ Clubs | get_athlete_clubs, get_club_activities, get_club_members |
Design Decisions
For a detailed list of architectural choices, unit standardizations, and LLM-specific optimizations, please refer to: 👉 docs/DESIGN_DECISIONS.md
CI/CD (Gitea Actions)
Our pipeline (.gitea/workflows/cicd.yml) is fully automated:
- Linting: Every push/PR is checked with
ruff. - Multi-Arch Builds: Builds
amd64andarm64images simultaneously using QEMU and DinD. - Smart Tagging:
- Pushes to
mainare tagged as:latest. - Git Tags (e.g.,
v1.2.0) trigger a versioned build and automatically update the Gitea Release description with the correctdocker pullcommand.
- Pushes to
Troubleshooting
[Errno 48] Address already in use
lsof -ti :8000 | xargs kill -9
401 Unauthorized
Your token expired. Run uv run auth to refresh.
🛠️ Development & Testing
1. Local Testing with MCP Inspector
The MCP Inspector is the best way to test the server without a full LLM client.
Option A: Test via STDIO (Fastest) This runs the server directly in your terminal (perfect for local debugging):
npx @modelcontextprotocol/inspector uv run server
Option B: Test via SSE (Remote/Docker)
If the server is already running (e.g., at http://localhost:8000):
- Open https://inspector.modelcontextprotocol.io/
- Transport: Streamable HTTP
- URL:
http://localhost:8000/mcp
2. Manual SSE Health Check
You can verify if the server is responding to SSE requests using curl:
curl -v -X POST http://localhost:8000/mcp
(It should return an SSE stream starting with event: endpoint)
3. Linting & Formatting
We use ruff for code quality:
# Run the check
uv run ruff check src
# Run the formatter
uv run ruff format src
4. Build Multi-Arch Images
To test if the multi-arch Docker build works locally (requires Docker Buildx):
docker buildx build --platform linux/amd64,linux/arm64 -t strava-mcp-server:test .
5. Git Hooks
Two hooks are provided in scripts/hooks/ — install them both after cloning:
cp scripts/hooks/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
cp scripts/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
pre-commit — Lint & Format check
Runs on staged .py files before every commit.
- 🔍
ruff check— linting - 🎨
ruff format --check— formatting - 🔧 Fix:
uv run ruff check --fix+uv run ruff format - ⚡ Bypass:
git commit --no-verify
pre-push — Unit tests
Runs the full unit test suite before every push.
- 🧪
pytest tests/unit/ -q - ⚡ Bypass:
git push --no-verify
6. Unit Tests
Fast, offline unit tests for pure functions and MCP helpers (no Strava API required).
# Run all unit tests
uv run pytest tests/unit/ -v
# Run with coverage (if pytest-cov is installed)
uv run pytest tests/unit/ --cov=strava_mcp_server
Test coverage:
| Module | Tests |
|---|---|
utils.py — parse_iso_to_unix |
None, empty, invalid, UTC, offset, date-only |
utils.py — format_date_iso |
Normalization, None, datetime object, invalid |
utils.py — format_date_human |
German format, None, datetime object, regex pattern |
tools/* — _resource() |
Type, mimeType, URI, JSON validity, audience |
tools/* — _user_text() |
Type, text value, audience |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file strava_mcp_server_hnrx-0.1.0.tar.gz.
File metadata
- Download URL: strava_mcp_server_hnrx-0.1.0.tar.gz
- Upload date:
- Size: 851.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e3c46f533786bbf7270ae39626829dd7fabe4958cefa6e4c6a0eb747819136c
|
|
| MD5 |
8156b43ceeec293d9c538ee4638ac011
|
|
| BLAKE2b-256 |
8b3242b346a497f8cfc3b94095099058567dbc12772ec46ad258388edf2bb811
|
File details
Details for the file strava_mcp_server_hnrx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: strava_mcp_server_hnrx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bf6cf4a8bcecdac33bcaf980a533c30e1817c66b986fd302871f40017de7a3b
|
|
| MD5 |
b08419bc23c5fa496c894f196b74769d
|
|
| BLAKE2b-256 |
f3b4ed534c464feed8d65253de47e244c002dd4ccb44bfb7fd0d345440bdbd78
|