go-strava-mcp
Strava MCP server (Go)
Give Claude, Cursor, and other MCP clients real access to your Strava data.
Activities, routes, streams, athlete stats, clubs, uploads — one small binary, no runtime.
14 tools · server id strava · single binary · OAuth that just works
Drop it into your MCP config and ask your agent for recent runs, HR streams, YTD totals, or to update an activity description — over stdio, with tokens stored on your machine.
| Service |
What agents can do |
| Activities |
List, get, create, update; zones and streams |
| Routes |
List and get saved maps / planned routes |
| URLs |
Resolve strava.app.link share links and fetch the resource |
| Athlete |
Profile and aggregate stats |
| Clubs |
Recent club member activities |
| Uploads |
Push FIT / TCX / GPX and poll processing |
Built for local, single-user AI tool use. Sibling MCP servers in the same style: google-mcp, go-garmin.
Why this one
- Zero runtime — download a binary (or
go install) and run; no Python, no Node
- Service-first tool names — hosts expose
strava__activities_list, not ambiguous get_activities (aligned with google-mcp)
- Short server id — MCP server name is
strava; binary / CLI is strava-mcp
- Local-first auth —
strava-mcp auth once; tokens under ~/.strava/ (or $DATA_DIR/.strava/ in gantry); refresh is silent and coalesced with singleflight
- Works where you already work — Claude Desktop, Cursor, Claude Code, and any stdio MCP client
Quick start
1. Strava API app
- Create an application at Strava API settings
- Authorization Callback Domain — one hostname only (no
localhost; … / comma lists). Use shotah.github.io for chat /auth strava (Pages catch page). localhost / 127.0.0.1 stay whitelisted
for laptop strava-mcp auth even with that set. Forks: your Pages host or
STRAVA_OAUTH_REDIRECT_URI — see
ai-gantry docs/auth.md.
Chat paste flow is implemented; smoke-test before relying on it.
- Note the Client ID and Client Secret
2. Install
Pre-built binary (no Go required) — grab the archive for your platform from Releases:
| Platform |
File |
| Linux x86_64 |
strava-mcp_*_linux_amd64.tar.gz |
| Linux ARM64 |
strava-mcp_*_linux_arm64.tar.gz |
| macOS Apple Silicon |
strava-mcp_*_darwin_arm64.tar.gz |
| macOS Intel |
strava-mcp_*_darwin_amd64.tar.gz |
| Windows x86_64 |
strava-mcp_*_windows_amd64.zip |
tar xzf strava-mcp_*_darwin_arm64.tar.gz
chmod +x strava-mcp
mv strava-mcp ~/.local/bin/
macOS Gatekeeper: if the binary was downloaded from the browser, clear quarantine first:
xattr -d com.apple.quarantine strava-mcp
Or with Go (1.26+):
go install github.com/shotah/go-strava-mcp@latest
3. Environment
export STRAVA_CLIENT_ID="your_client_id"
export STRAVA_CLIENT_SECRET="your_client_secret"
# optional: STRAVA_TOKEN_PATH=~/.strava/tokens.json
4. Authenticate
strava-mcp auth
Opens a browser, completes OAuth, writes tokens locally. You should see Authenticated as [Your Name]!.
Headless / chat paste (needs callback domain shotah.github.io):
strava-mcp auth url → approve → strava-mcp auth exchange <code>.
See ai-gantry docs/auth.md
(smoke-test recommended).
5. MCP client config
Use server id strava so hosts expose tools as strava__activities_list.
{
"mcpServers": {
"strava": {
"command": "strava-mcp",
"env": {
"STRAVA_CLIENT_ID": "your_client_id",
"STRAVA_CLIENT_SECRET": "your_client_secret"
}
}
}
}
Restart the client. Ask things like “what were my last five runs?”, “list my saved routes”, or “open this strava.app.link and show the map”.
Host-facing names are {server}__{tool} → e.g. strava__activities_list.
| Tool |
Description |
activities_list |
Recent activities (date filters, pagination) |
activities_get |
Full activity detail (laps, splits, segments) |
activities_create |
Create a manual activity |
activities_update |
Update name, description, sport type, gear |
activities_get_zones |
HR / power zone distribution |
activities_get_streams |
Time-series telemetry (HR, GPS, power, …) |
athlete_get |
Authenticated athlete profile |
athlete_get_stats |
Recent / YTD / all-time totals |
clubs_list_activities |
Recent activities from club members |
uploads_create |
Upload FIT / TCX / GPX |
uploads_get |
Upload processing status |
routes_list |
Saved routes / planned maps (pagination) |
routes_get |
Route detail including map polylines |
urls_resolve |
Resolve strava.app.link (or full) URLs and fetch the map/resource |
Release builds also register utility_check_update / utility_self_update (not present on dev builds).
Configuration
| Variable |
Required |
Default |
Description |
STRAVA_CLIENT_ID |
Yes |
— |
Strava API client ID |
STRAVA_CLIENT_SECRET |
Yes |
— |
Strava API client secret |
STRAVA_TOKEN_PATH |
No |
$DATA_DIR/.strava/tokens.json when DATA_DIR is set, else ~/.strava/tokens.json |
Token store path |
STRAVA_OAUTH_BIND |
No |
0.0.0.0 |
OAuth callback bind host (0.0.0.0 for Docker -p; use 127.0.0.1 for loopback-only). redirect_uri stays http://localhost:19876/callback |
STRAVA_OAUTH_REDIRECT_URI |
No |
Pages catch URL |
Override redirect for auth url / exchange (default: https://shotah.github.io/ai-gantry/oauth-catch/) |
STRAVA_MCP_NO_UPDATE_CHECK |
No |
unset |
Set to skip background update check on startup |
CLI
| Command |
Description |
strava-mcp |
Start MCP server on stdio (default) |
strava-mcp auth |
OAuth browser flow (localhost callback) |
strava-mcp auth url |
Print authorize URL + hold PKCE pending for chat paste |
strava-mcp auth exchange <code> |
Exchange pasted code → tokens on disk |
strava-mcp --version |
Version / commit / build date |
strava-mcp --check-update |
Print whether a newer release exists |
strava-mcp --update |
Self-update from GitHub Releases |
strava-mcp --debug |
Debug logging on stderr |
Stdout is reserved for MCP JSON-RPC; all logs go to stderr.
Development
make tools # goimports-reviser + golangci-lint
make install-hooks # pre-commit: fmt → lint → test + ≥70% coverage
make check # same gate as CI
make coverage # coverprofile + threshold
go test ./...
STRAVA_CLIENT_ID=… STRAVA_CLIENT_SECRET=… go run . --debug
CI builds, lints, enforces ≥70% coverage on ./..., and publishes a coverage badge to gh-pages. Releases are cut with make release (GoReleaser on v* tags).
See CONTRIBUTING.md and SECURITY.md.
License
ISC
Forked from Stealinglight/StravaMCP; module path, tooling, and MCP naming reshaped for the shotah MCP set.
Links