strava-mcp: A Local MCP Server That Puts Your Strava Data Behind a Browser-Based OAuth Flow
A Model Context Protocol (MCP) server that connects to Strava API, providing tools to access Strava data through LLMs
At a glance
- What is it?
- A TypeScript MCP server published as @r-huijts/strava-mcp-server that exposes Strava account, activity, segment and route tools to Claude Desktop and Claude Code. Its most interesting design decision is that OAuth setup happens in a browser window opened by the tool call, not through environment variables.
- Who is it for?
- Adopt it if you run Claude Desktop or Claude Code, already have a Strava API application, and want activity, lap, segment and route data reachable from a chat session without writing a client. Do not adopt it if you need unattended or multi-user access, since the OAuth flow assumes one person at a browser and credentials sit in ~/.config/strava-mcp/config.json on that machine.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 95 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem: Strava Data Is Readable but Not Conversational
Strava exposes an API, and anyone with a client ID and secret can call it. The friction is not authentication in the abstract. It is that answering a question like how far did I run this month means writing a script, handling pagination, mapping activity types, and formatting the result. The README frames the project around exactly that gap: connect Claude to a Strava account and ask questions in plain English. The intended user is a single athlete who already uses Claude Desktop or Claude Code and wants their own training history available inside that session. It is not a coaching platform, not a team dashboard, and not a data warehouse loader. The scope is one account, one machine, one assistant.
Architecture: A stdio MCP Server With a Local Config File
The server speaks MCP over stdio. Claude Desktop launches it as a child process, and Claude Code registers it with the stdio transport. There is no hosted component described in the README, so the process runs on your machine and talks to the Strava API directly. State lives in two places. Credentials and tokens are written to ~/.config/strava-mcp/config.json, and the README states they persist across sessions. The Strava application identity (Client ID and Client Secret) is entered by the user during setup rather than supplied as environment variables at launch. That is the architectural choice worth noting. Most MCP servers of this kind expect secrets in the config block or in the environment, which makes them scriptable but also means secrets end up in a JSON file that people paste into issues. This project moves the secret entry into a browser step at runtime and keeps the launch config free of credentials. The trade-off is that the first run cannot be fully automated.
Getting It Running: Three Paths and the Exact Commands
The recommended path requires no install. Add a block to the Claude Desktop configuration file, which on macOS is ~/Library/Application Support/Claude/claude_desktop_config.json and on Windows is %APPDATA%\Claude\claude_desktop_config.json. The block names the server strava, sets command to npx, and passes args ["-y", "@r-huijts/strava-mcp-server"]. Restart Claude Desktop, then tell Claude to connect your Strava account. For Claude Code, the README gives a single command: claude mcp add --transport stdio strava -- npx @r-huijts/strava-mcp-server. You can check registration with claude mcp list, which the README shows printing a health line for the strava entry. The global install path is npm install -g @r-huijts/strava-mcp-server, after which the config block uses command strava-mcp-server with no args. The README flags a naming detail here: the package is scoped as @r-huijts/strava-mcp-server but the executable is still strava-mcp-server, kept for backward compatibility. Building from source is git clone, npm install, npm run build, then pointing the config at /path/to/strava-mcp/dist/server.js with command node. Note the dist/server.js path, since that is the entry point the README names.
The OAuth Flow Runs Through a Browser Window, Not a Token File
On first use, saying connect my Strava account opens a browser window with a setup page. You enter the Client ID and Client Secret, click Continue to Strava, authorize on Strava's site, and see a success message. The README states credentials are then saved to ~/.config/strava-mcp/config.json. Before any of this you need a Strava API application, created at strava.com/settings/api. The README is specific about one field: the Authorization Callback Domain must be localhost. Application name, category and website are described as arbitrary. This is the part that trips people up, because the callback domain is not a free-text field in practice and a mismatch produces a redirect failure rather than a helpful error. If authorization fails, check that field first. Reconnection is handled by asking to connect again with force set to true, and disconnection clears stored tokens.
What the Tool Surface Actually Covers
The README groups tools into account and profile, activities, and (by implication from the example prompts) routes and segments. Confirmed account operations include connecting, checking connection status, disconnecting, retrieving the profile, listing shoes with usage distance, and retrieving heart rate and power training zones. Confirmed activity operations include listing recent activities, fetching activities with filters such as all runs from January, retrieving detail for a single activity by ID, and a lap-by-lap breakdown. The example prompts also reference starred segments, popular segments near a location, and exporting a route as GPX. The README's tool table is truncated in the material available, so the precise tool names, argument schemas and the complete list cannot be verified here. Treat the tool list as larger than what is documented above but not fully enumerated. If a specific endpoint matters to you, confirm it exists before committing.
Where This Design Breaks Down
The browser-based setup is the feature and the limitation. It assumes a human at a graphical session on the same machine as the MCP server. On a headless box, inside a container, or over SSH without X forwarding, that window has nowhere to appear. There is no documented path for supplying credentials non-interactively, and the README does not describe a token refresh flow or what happens when the Strava token expires. The config file also means the secret is stored in plaintext at a predictable path under the user's home directory. For a personal laptop that is a reasonable trade. For a shared machine it is not. The single-account model is a second boundary: the README describes one Strava connection per installation, so using it for two athletes means two config directories or two machines. Rate limiting is not discussed in the material, which matters because a chat session that asks for a year of activities will issue many calls.
The Alternative: Calling the Strava API Directly
The obvious alternative is a short script against the Strava API, using the official strava-v3 Node client or Python's stravalib. The difference is where the intelligence sits. With a script you decide the queries in advance and get typed, reproducible output; the LLM never sees the raw payload. With strava-mcp the model chooses which tools to call, which means the same question can produce different API call patterns on different days, and the answer depends on how the model interprets an activity ID or a date range. The script is better when you want a fixed weekly report, a scheduled export, or anything that must run without a human present. The MCP server is better when the question is not known in advance. A second alternative is a general HTTP or fetch MCP server pointed at the Strava API, which avoids installing anything specific but pushes OAuth handling and pagination onto the model, and that tends to go badly.
Maintenance, Licence and What to Verify Before Adopting
The project is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence, and it is the same licence many MCP servers use, so it should not be a blocker for internal tooling. It does not, however, grant anything with respect to Strava's own terms of service, which govern API use separately and are not covered in the README. No releases were retrieved in the material, so there is no changelog to read and no version history to reason about. The README notes the executable name is pinned for backward compatibility, which is a small signal that the package has been renamed at least once. On upgrade cost: the npx path always pulls the latest version, so you get fixes without asking and you also get breaking changes without asking. If that matters, pin a version in the args array or use the global install and upgrade deliberately. Before adopting, verify three things: that your Strava API app has the callback domain set to localhost, that the tool list covers the endpoints you actually need, and that ~/.config/strava-mcp/config.json sits somewhere you are comfortable storing a client secret.
Editorial conclusion
Adopt it if you run Claude Desktop or Claude Code, already have a Strava API application, and want activity, lap, segment and route data reachable from a chat session without writing a client. Do not adopt it if you need unattended or multi-user access, since the OAuth flow assumes one person at a browser and credentials sit in ~/.config/strava-mcp/config.json on that machine. Before installing, create the Strava API app at strava.com/settings/api, confirm the Authorization Callback Domain field is set to localhost, and verify that the tool list actually covers the endpoints you need, because the README's table is truncated and the full set is not documented in the material available here.
Community notes