Strava from your terminal. Pipe it, script it, automate it.
Exploring CLI tools as skills for AI agents. Background below.
- All your Strava data — activities, stats, segments, routes, clubs, gear
- Script and automate — composable with jq, pipes, xargs, and standard Unix tools
- AI agent ready — install the skill for Claude, Cursor, and other assistants
- Flexible output — JSON for scripts, CSV for spreadsheets, tables for humans
curl -fsSL https://raw.githubusercontent.com/eddmann/strava-cli/main/install.sh | shDownloads the pre-built binary for your platform (macOS/Linux) to ~/.local/bin.
brew install eddmann/tap/strava-cli
Requires Python 3.10+ and uv.
uvx strava-terminal --help uv tool install strava-terminal
The PyPI package is strava-terminal for uvx/uv tool usage; the project remains Strava CLI and the primary command remains strava.
git clone https://github.com/eddmann/strava-cli
cd strava-cli
make deps
uv run strava --helpstrava auth login
First time? You'll be guided to create a Strava API application:
- Go to https://www.strava.com/settings/api
- Create an application (set callback domain to
localhost) - Enter your Client ID and Client Secret when prompted
Credentials and tokens are stored in ~/.config/strava-cli/config.toml.
# List recent activities strava activities list --limit 10 # Get a specific activity strava activities get 12345678 # Get your athlete profile strava athlete # Get your stats strava athlete stats
| Flag | Short | Description |
|---|---|---|
--format |
-f |
Output format: json (default), jsonl, csv, tsv, human |
--fields |
Comma-separated list of fields to include | |
--no-header |
Omit header row in CSV/TSV output | |
--verbose |
-v |
Verbose output to stderr |
--quiet |
-q |
Suppress non-essential output |
--config |
-c |
Path to config file |
--profile |
-p |
Named profile to use |
--version |
-V |
Show version and exit |
strava context # Get full context: athlete, stats, gear, clubs, recent activities strava context --activities 10 # Include more recent activities strava context --focus stats,gear # Only specific sections strava context --no-clubs # Exclude clubs
By default, the OAuth flow requests the scopes needed to read profile and activity data, star or unstar segments, and create, update, upload, or delete activities.
strava auth login # OAuth browser flow strava auth logout # Clear stored credentials strava auth logout --revoke # Also revoke on Strava servers strava auth status # Show authentication status strava auth refresh # Force token refresh
strava activities list [--after DATE] [--before DATE] [--limit N] strava activities get <ID> [--include-efforts] strava activities create --name NAME --sport-type TYPE --start ISO8601 --elapsed SECS strava activities update <ID> [--name NAME] [--description DESC] strava activities delete <ID> [--force] strava activities streams <ID> [--keys time,distance,heartrate,...] strava activities laps <ID> strava activities zones <ID> strava activities comments <ID> strava activities kudos <ID>
strava athlete # Get profile strava athlete stats # Get statistics strava athlete zones # Get HR/power zones
strava segments get <ID> strava segments starred [--limit N] strava segments star <ID> strava segments unstar <ID> strava segments explore --bounds SW_LAT,SW_LNG,NE_LAT,NE_LNG [--activity-type running|riding]
strava efforts get <ID> strava efforts list --segment-id <ID> [--start DATE] [--end DATE]
strava routes list [--limit N] strava routes get <ID> strava routes export <ID> --format gpx|tcx [-o FILE] strava routes streams <ID>
strava clubs list strava clubs get <ID> strava clubs members <ID> [--limit N] strava clubs activities <ID> [--limit N]
strava gear get <GEAR_ID> # e.g., b12345678 for bikes, g12345678 for shoes
strava upload [--data-type fit|gpx|tcx] [--activity-type TYPE] [--name NAME] [--wait] <FILE> strava upload status <UPLOAD_ID>
# Filter runs over 10km (distance in meters) strava activities list | jq '.[] | select(.sport_type=="Run" and .distance > 10000)' # Total distance this month in km strava activities list --after 2025-12-01 | jq '[.[].distance] | add / 1000' # Calculate pace for recent runs (min/km) strava activities list --limit 5 | jq '.[] | select(.sport_type=="Run") | {name, pace: ((.moving_time/60) / (.distance/1000) | floor)}'
Config file location: ~/.config/strava-cli/config.toml
[client] id = "12345" secret = "abc123..." [auth] access_token = "..." refresh_token = "..." expires_at = 1234567890 athlete_id = 12345 scopes = ["read", "profile:read_all", "profile:write", "activity:read_all", "activity:write"] [defaults] format = "json" limit = 30 # Multiple profiles for different accounts [profiles.work] access_token = "..." refresh_token = "..."
| Variable | Description |
|---|---|
STRAVA_CLIENT_ID |
OAuth client ID (or use config file) |
STRAVA_CLIENT_SECRET |
OAuth client secret (or use config file) |
STRAVA_ACCESS_TOKEN |
Override access token |
STRAVA_REFRESH_TOKEN |
Override refresh token |
STRAVA_CONFIG |
Config file path |
STRAVA_FORMAT |
Default output format |
STRAVA_PROFILE |
Default profile |
This CLI is available as an Agent Skill — it works with Claude Code, Cursor, and other compatible AI agents. See SKILL.md for the skill definition.
curl -fsSL https://raw.githubusercontent.com/eddmann/strava-cli/main/install-skill.sh | shInstalls the skill to ~/.claude/skills/strava/ and ~/.cursor/skills/strava/. Agents will auto-detect when you ask about Strava/fitness data.
git clone https://github.com/eddmann/strava-cli cd strava-cli make deps # Install dependencies make test # Run tests make run CMD="activities list --limit 5" # Run command
I recently built strava-mcp, an MCP server for Strava. This got me thinking about alternative approaches to giving AI agents capabilities.
There's been a lot of discussion around the heavyweight nature of MCP. An alternative approach is to give agents discoverable skills via well-documented CLI tooling. Give an LLM a terminal and let it use composable CLI tools to build up functionality and solve problems — the Unix philosophy applied to AI agents.
This project is an exploration of Claude Code Skills and the emerging Agent Skills standard for AI-tool interoperability. The goal was to build a CLI that works seamlessly as both:
- A traditional Unix tool — composable, pipe-friendly, machine-readable
- An AI agent skill — structured output, comprehensive documentation, predictable behavior
Going forward, another approach worth exploring is going one step further than CLI and providing a code library that agents can import and use directly.
MIT
Built on top of stravalib.
