strava-activity-mcp-server 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- strava_activity_mcp_server/strava_activity_mcp_server.py +24 -7
- strava_activity_mcp_server-0.1.2.dist-info/METADATA +140 -0
- strava_activity_mcp_server-0.1.2.dist-info/RECORD +8 -0
- strava_activity_mcp_server-0.1.0.dist-info/METADATA +0 -21
- strava_activity_mcp_server-0.1.0.dist-info/RECORD +0 -8
- {strava_activity_mcp_server-0.1.0.dist-info → strava_activity_mcp_server-0.1.2.dist-info}/WHEEL +0 -0
- {strava_activity_mcp_server-0.1.0.dist-info → strava_activity_mcp_server-0.1.2.dist-info}/entry_points.txt +0 -0
- {strava_activity_mcp_server-0.1.0.dist-info → strava_activity_mcp_server-0.1.2.dist-info}/licenses/LICENSE +0 -0
@@ -8,9 +8,26 @@ import urllib.parse
|
|
8
8
|
|
9
9
|
@mcp.tool("strava://auth/url")
|
10
10
|
|
11
|
-
def get_auth_url(client_id):
|
12
|
-
"""Return the Strava OAuth authorization URL.
|
13
|
-
|
11
|
+
def get_auth_url(client_id: int | None = None):
|
12
|
+
"""Return the Strava OAuth authorization URL. If client_id is not provided,
|
13
|
+
read it from the STRAVA_CLIENT_ID environment variable."""
|
14
|
+
if client_id is None:
|
15
|
+
client_id_env = os.getenv("STRAVA_CLIENT_ID")
|
16
|
+
if not client_id_env:
|
17
|
+
return {"error": "STRAVA_CLIENT_ID environment variable is not set"}
|
18
|
+
try:
|
19
|
+
client_id = int(client_id_env)
|
20
|
+
except ValueError:
|
21
|
+
return {"error": "STRAVA_CLIENT_ID must be an integer"}
|
22
|
+
|
23
|
+
params = {
|
24
|
+
"client_id": client_id,
|
25
|
+
"response_type": "code",
|
26
|
+
"redirect_uri": "https://developers.strava.com/oauth2-redirect/",
|
27
|
+
"approval_prompt": "force",
|
28
|
+
"scope": "read,activity:read_all",
|
29
|
+
}
|
30
|
+
return "https://www.strava.com/oauth/authorize?" + urllib.parse.urlencode(params)
|
14
31
|
|
15
32
|
|
16
33
|
|
@@ -80,17 +97,17 @@ def refresh_access_token(
|
|
80
97
|
|
81
98
|
|
82
99
|
@mcp.tool("strava://athlete/stats")
|
83
|
-
def get_athlete_stats(token: str) ->
|
84
|
-
"""Retrieve athlete activities
|
100
|
+
def get_athlete_stats(token: str) -> object:
|
101
|
+
"""Retrieve athlete activities using an access token."""
|
85
102
|
url = "https://www.strava.com/api/v3/athlete/activities?per_page=60"
|
86
103
|
headers = {
|
87
104
|
"accept": "application/json",
|
88
105
|
"authorization": f"Bearer {token}"
|
89
106
|
}
|
90
|
-
import json
|
91
107
|
response = requests.get(url, headers=headers)
|
92
108
|
response.raise_for_status()
|
93
|
-
|
109
|
+
# Return the parsed JSON (dict or list) instead of a JSON string so the return type matches.
|
110
|
+
return response.json()
|
94
111
|
|
95
112
|
if __name__ == "__main__":
|
96
113
|
mcp.run(transport="stdio") # Run the server, using standard input/output for communication
|
@@ -0,0 +1,140 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: strava-activity-mcp-server
|
3
|
+
Version: 0.1.2
|
4
|
+
Summary: Trying to implement environment variables for client_id
|
5
|
+
License-File: LICENSE
|
6
|
+
Requires-Python: >=3.13
|
7
|
+
Requires-Dist: build>=1.3.0
|
8
|
+
Requires-Dist: mcp[cli]>=1.16.0
|
9
|
+
Requires-Dist: twine>=6.2.0
|
10
|
+
Description-Content-Type: text/markdown
|
11
|
+
|
12
|
+
# Strava Activity MCP Server
|
13
|
+
[](https://opensource.org/licenses/gpl-3-0)[](https://www.python.org/downloads/release/python-3130/)
|
14
|
+
|
15
|
+
A small Model Context Protocol (MCP) server that exposes your Strava athlete data to language-model tooling.
|
16
|
+
|
17
|
+
This package provides a lightweight MCP server which communicates with the Strava API and exposes a few helper tools (authorization URL, token exchange/refresh, and fetching athlete activities) that language models or other local tools can call.
|
18
|
+
|
19
|
+
The project is intended to be used locally (for example with Claude MCP integrations) and is published on PyPI as `strava-activity-mcp-server`.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Install from PyPI with pip (recommended inside a virtual environment):
|
24
|
+
|
25
|
+
```powershell
|
26
|
+
pip install strava-activity-mcp-server
|
27
|
+
```
|
28
|
+
|
29
|
+
## Requirements
|
30
|
+
|
31
|
+
- Python >= 3.13 (see `pyproject.toml`)
|
32
|
+
- The package depends on `mcp[cli]` and `requests` (installed from PyPI).
|
33
|
+
|
34
|
+
## Quick start
|
35
|
+
|
36
|
+
After installing, you can run the MCP server using the provided console script or by importing and calling `main()`.
|
37
|
+
|
38
|
+
Run via the console script (entry point defined in `pyproject.toml`):
|
39
|
+
|
40
|
+
```powershell
|
41
|
+
strava-activity-mcp-server
|
42
|
+
```
|
43
|
+
|
44
|
+
Or, from Python:
|
45
|
+
|
46
|
+
```python
|
47
|
+
from strava_activity_mcp_server import main
|
48
|
+
main()
|
49
|
+
```
|
50
|
+
|
51
|
+
By default the server starts the MCP runtime; when used with an MCP-aware client (for example Claude MCP integrations) the exposed tools become callable.
|
52
|
+
|
53
|
+
## Authentication (Strava OAuth)
|
54
|
+
|
55
|
+
This server requires Strava OAuth credentials to access athlete data. You will need:
|
56
|
+
|
57
|
+
- STRAVA_CLIENT_ID
|
58
|
+
- STRAVA_CLIENT_SECRET
|
59
|
+
- STRAVA_REFRESH_TOKEN (or a short-lived access token obtained from the authorization flow)
|
60
|
+
|
61
|
+
Steps:
|
62
|
+
|
63
|
+
1. Create a Strava API application at https://www.strava.com/settings/api and note your Client ID and Client Secret. Use `localhost` as the Authorization Callback Domain.
|
64
|
+
2. Open the authorization URL produced by the `strava://auth/url` tool (see Tools below) in a browser to obtain an authorization code.
|
65
|
+
3. Exchange the code for tokens using `strava://auth/token` or use the included helper to save refresh/access tokens to your environment.
|
66
|
+
|
67
|
+
For local testing you can also manually set the environment variables before running the server:
|
68
|
+
|
69
|
+
```powershell
|
70
|
+
$env:STRAVA_CLIENT_ID = "<your client id>";
|
71
|
+
$env:STRAVA_CLIENT_SECRET = "<your client secret>";
|
72
|
+
$env:STRAVA_REFRESH_TOKEN = "<your refresh token>";
|
73
|
+
strava-activity-mcp-server
|
74
|
+
```
|
75
|
+
|
76
|
+
Note: Keep secrets out of version control. Use a `.env` file and a tool such as `direnv` or your system secrets manager for convenience.
|
77
|
+
|
78
|
+
## Exposed Tools (what the server provides)
|
79
|
+
|
80
|
+
The MCP server exposes the following tools (tool IDs shown):
|
81
|
+
|
82
|
+
- `strava://auth/url` — Build the Strava OAuth authorization URL. Input: `client_id` (int). Output: URL string to open in a browser.
|
83
|
+
- `strava://auth/token` — Exchange an authorization code for access + refresh tokens. Inputs: `code` (str), `client_id` (int), `client_secret` (str). Output: token dict (with `access_token`, `refresh_token`).
|
84
|
+
- `strava://athlete/stats` — Fetch recent athlete activities. Input: `token` (str). Output: JSON with activity list.
|
85
|
+
|
86
|
+
These tools map to the functions implemented in `src/strava_activity_mcp_server/strava_activity_mcp_server.py` and are intended to be called by MCP clients.
|
87
|
+
|
88
|
+
## Example flows
|
89
|
+
|
90
|
+
1) Get an authorization URL and retrieve tokens
|
91
|
+
|
92
|
+
- Call `strava://auth/url` with your `client_id` and open the returned URL in your browser.
|
93
|
+
- After authorizing, Strava will provide a `code`. Call `strava://auth/token` with `code`, `client_id`, and `client_secret` to receive `access_token` and `refresh_token`.
|
94
|
+
|
95
|
+
2) Fetch recent activities
|
96
|
+
|
97
|
+
- Use `strava://athlete/stats` with a valid access token. If the access token is expired, use the refresh flow to get a new access token.
|
98
|
+
|
99
|
+
## Developer notes
|
100
|
+
|
101
|
+
- The package entry point calls `mcp.run()` which runs the MCP server. If you want to change transport or logging settings, modify `src/strava_activity_mcp_server/__init__.py` or `strava_activity_mcp_server.py`.
|
102
|
+
- The code uses the `requests` library for HTTP calls.
|
103
|
+
|
104
|
+
|
105
|
+
### Client config example and quick inspector test
|
106
|
+
|
107
|
+
Any MCP-capable client can launch the server using a config similar to the following (example file often called `config.json`):
|
108
|
+
|
109
|
+
```json
|
110
|
+
{
|
111
|
+
"command": "uvx",
|
112
|
+
"args": [
|
113
|
+
"strava-activity-mcp-server"
|
114
|
+
]
|
115
|
+
}
|
116
|
+
```
|
117
|
+
|
118
|
+
To quickly test the server using the Model Context Protocol inspector tool, run:
|
119
|
+
|
120
|
+
```powershell
|
121
|
+
npx @modelcontextprotocol/inspector uvx strava-mcp-server
|
122
|
+
```
|
123
|
+
|
124
|
+
This will attempt to start the server with the `uvx` transport and connect the inspector to the running MCP server instance named `strava-mcp-server`.
|
125
|
+
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
Contributions are welcome. Please open issues or pull requests that include a clear description and tests where applicable.
|
130
|
+
|
131
|
+
## License
|
132
|
+
|
133
|
+
This project is licensed under the GNU GENERAL PUBLIC LICENSE — see the `LICENSE` file for details.
|
134
|
+
|
135
|
+
## Links
|
136
|
+
|
137
|
+
- Source: repository root
|
138
|
+
- Documentation note: see `README.md` for an example MCP configuration
|
139
|
+
|
140
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
strava_activity_mcp_server/__init__.py,sha256=NgXC8CeBg0qFRHdZJJKjQlX9_RwSETJ9O6PNy0leOTI,107
|
2
|
+
strava_activity_mcp_server/__main__.py,sha256=SAdVoObdjb5UP4MY-Y2_uCXpnthB6hgxlb1KNVNgOrc,58
|
3
|
+
strava_activity_mcp_server/strava_activity_mcp_server.py,sha256=rZgRFH4esSiOY-ouceIR046hzTpOeN6xDE_eRZPY07U,3836
|
4
|
+
strava_activity_mcp_server-0.1.2.dist-info/METADATA,sha256=BnGhlTQEfRsDn4BMMEclraxVnwHjxowYuhseCLPvpk0,6043
|
5
|
+
strava_activity_mcp_server-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
+
strava_activity_mcp_server-0.1.2.dist-info/entry_points.txt,sha256=F6PO_DBSThhtmX2AC-tu2MIiCJkGi31LCaQJxfUzZ5g,79
|
7
|
+
strava_activity_mcp_server-0.1.2.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
8
|
+
strava_activity_mcp_server-0.1.2.dist-info/RECORD,,
|
@@ -1,21 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: strava-activity-mcp-server
|
3
|
-
Version: 0.1.0
|
4
|
-
Summary: Add your description here
|
5
|
-
License-File: LICENSE
|
6
|
-
Requires-Python: >=3.13
|
7
|
-
Requires-Dist: build>=1.3.0
|
8
|
-
Requires-Dist: mcp[cli]>=1.16.0
|
9
|
-
Requires-Dist: twine>=6.2.0
|
10
|
-
Description-Content-Type: text/markdown
|
11
|
-
|
12
|
-
# strava-mcp-server
|
13
|
-
MCP server that retrieves user activity data from Strava.
|
14
|
-
|
15
|
-
.venv\Scripts\activate
|
16
|
-
|
17
|
-
uv init --build-backend "hatchling"
|
18
|
-
|
19
|
-
uv add mcp["cli"]
|
20
|
-
|
21
|
-
uv run mcp dev scr/strava_mcp_server/strava_mcp_server.py
|
@@ -1,8 +0,0 @@
|
|
1
|
-
strava_activity_mcp_server/__init__.py,sha256=NgXC8CeBg0qFRHdZJJKjQlX9_RwSETJ9O6PNy0leOTI,107
|
2
|
-
strava_activity_mcp_server/__main__.py,sha256=SAdVoObdjb5UP4MY-Y2_uCXpnthB6hgxlb1KNVNgOrc,58
|
3
|
-
strava_activity_mcp_server/strava_activity_mcp_server.py,sha256=1Xvo763lIP9m9lBoAYZ2Al86KXw2ozdMSkF_bWl_JxM,3245
|
4
|
-
strava_activity_mcp_server-0.1.0.dist-info/METADATA,sha256=cYlysawB9SAJX7FcPBIUUUsewHFObVu-DqDkOgpkcvQ,497
|
5
|
-
strava_activity_mcp_server-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
6
|
-
strava_activity_mcp_server-0.1.0.dist-info/entry_points.txt,sha256=F6PO_DBSThhtmX2AC-tu2MIiCJkGi31LCaQJxfUzZ5g,79
|
7
|
-
strava_activity_mcp_server-0.1.0.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
8
|
-
strava_activity_mcp_server-0.1.0.dist-info/RECORD,,
|
{strava_activity_mcp_server-0.1.0.dist-info → strava_activity_mcp_server-0.1.2.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|