Strava from your terminal. Pipe it, script it, automate it.
Exploring CLI tools as skills for AI agents. Background below.
Features
- 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
Installation
Quick Install (Recommended)
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.
Homebrew
brew install eddmann/tap/strava-cli
Using uv/pipx
Requires Python 3.10+ and uv.
uv tool install git+https://github.com/eddmann/strava-cli.git
From Source
git clone https://github.com/eddmann/strava-cli
cd strava-cli
uv sync
uv run strava --helpQuick Start
1. Authenticate
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.
2. Use the CLI
# 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
Command Reference
Global Options
| 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 |
Context (LLM Helper)
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
Authentication
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
Activities
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>
Athlete
strava athlete # Get profile strava athlete stats # Get statistics strava athlete zones # Get HR/power zones
Segments
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]
Segment Efforts
strava efforts get <ID> strava efforts list --segment-id <ID> [--start DATE] [--end DATE]
Routes
strava routes list [--limit N] strava routes get <ID> strava routes export <ID> --format gpx|tcx [-o FILE] strava routes streams <ID>
Clubs
strava clubs list strava clubs get <ID> strava clubs members <ID> [--limit N] strava clubs activities <ID> [--limit N]
Gear
strava gear get <GEAR_ID> # e.g., b12345678 for bikes, g12345678 for shoes
Upload
strava upload <FILE> [--data-type fit|gpx|tcx] [--name NAME] [--wait] strava upload status <UPLOAD_ID>
Composability
# 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)}'
Configuration
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", "activity:read_all", "activity:write"] [defaults] format = "json" limit = 30 # Multiple profiles for different accounts [profiles.work] access_token = "..." refresh_token = "..."
Environment Variables
| 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 |
AI Agent Integration
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.
Install Agent Skill
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.
Development
git clone https://github.com/eddmann/strava-cli cd strava-cli make install # Install dependencies make test # Run tests make run CMD="activities list --limit 5" # Run command
Background
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.
License
MIT
Credits
Built on top of stravalib.
