strava-activity-mcp-server 0.2.4__py3-none-any.whl → 0.2.6__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.

Potentially problematic release.


This version of strava-activity-mcp-server might be problematic. Click here for more details.

@@ -118,8 +118,22 @@ async def get_athlete_stats(
118
118
  code: str,
119
119
  client_id: int | None = None,
120
120
  client_secret: str | None = None,
121
+ after: int | None = None,
122
+ before: int | None = None,
123
+ page: int | None = None,
124
+ per_page: int | None = None,
121
125
  ) -> dict:
122
- """Exchange an authorization code for access + refresh tokens and get athlete activities."""
126
+ """Exchange an authorization code for access + refresh tokens and get athlete activities with optional filters.
127
+
128
+ Args:
129
+ code: Authorization code from Strava OAuth
130
+ client_id: Strava client ID
131
+ client_secret: Strava client secret
132
+ after: An epoch timestamp to use for filtering activities that have taken place after a certain time
133
+ before: An epoch timestamp to use for filtering activities that have taken place before a certain time
134
+ page: The page of activities (default=1)
135
+ per_page: How many activities per page (default=30)
136
+ """
123
137
  if not code:
124
138
  return {"error": "authorization code is required"}
125
139
 
@@ -178,7 +192,24 @@ async def get_athlete_stats(
178
192
 
179
193
  # return {"tokens": tokens, "access_token": access_token, "refresh_token": refresh_token}
180
194
 
181
- url = "https://www.strava.com/api/v3/athlete/activities?per_page=60"
195
+ # Build URL with query parameters
196
+ params = []
197
+ if after is not None:
198
+ params.append(f"after={after}")
199
+ if before is not None:
200
+ params.append(f"before={before}")
201
+ if page is not None:
202
+ params.append(f"page={page}")
203
+ if per_page is not None:
204
+ params.append(f"per_page={per_page}")
205
+
206
+ # Default per_page to 30 if not specified (Strava API default)
207
+ if per_page is None:
208
+ params.append("per_page=30")
209
+
210
+ query_string = "&".join(params) if params else ""
211
+ url = f"https://www.strava.com/api/v3/athlete/activities?{query_string}"
212
+
182
213
  headers = {
183
214
  "accept": "application/json",
184
215
  "authorization": f"Bearer {access_token}"
@@ -197,12 +228,43 @@ async def get_athlete_stats(
197
228
  }
198
229
 
199
230
  @mcp.tool("strava://athlete/stats-with-token")
200
- async def get_athlete_stats_with_token(access_token: str) -> dict:
201
- """Get athlete activities using an existing access token."""
231
+ async def get_athlete_stats_with_token(
232
+ access_token: str,
233
+ after: int | None = None,
234
+ before: int | None = None,
235
+ page: int | None = None,
236
+ per_page: int | None = None
237
+ ) -> dict:
238
+ """Get athlete activities using an existing access token with optional filters.
239
+
240
+ Args:
241
+ access_token: Strava access token
242
+ after: An epoch timestamp to use for filtering activities that have taken place after a certain time
243
+ before: An epoch timestamp to use for filtering activities that have taken place before a certain time
244
+ page: The page of activities (default=1)
245
+ per_page: How many activities per page (default=30)
246
+ """
202
247
  if not access_token:
203
248
  return {"error": "access token is required"}
204
249
 
205
- url = "https://www.strava.com/api/v3/athlete/activities?per_page=60"
250
+ # Build URL with query parameters
251
+ params = []
252
+ if after is not None:
253
+ params.append(f"after={after}")
254
+ if before is not None:
255
+ params.append(f"before={before}")
256
+ if page is not None:
257
+ params.append(f"page={page}")
258
+ if per_page is not None:
259
+ params.append(f"per_page={per_page}")
260
+
261
+ # Default per_page to 30 if not specified (Strava API default)
262
+ if per_page is None:
263
+ params.append("per_page=30")
264
+
265
+ query_string = "&".join(params) if params else ""
266
+ url = f"https://www.strava.com/api/v3/athlete/activities?{query_string}"
267
+
206
268
  headers = {
207
269
  "accept": "application/json",
208
270
  "authorization": f"Bearer {access_token}"
@@ -218,11 +280,11 @@ async def get_athlete_stats_with_token(access_token: str) -> dict:
218
280
  return {"error": "API request failed", "status_code": response.status_code, "response": response.text, "error": str(e)}
219
281
 
220
282
  activities_data = response.json()
221
- return {
222
- "activities": activities_data,
223
- "count": len(activities_data) if isinstance(activities_data, list) else 0,
224
- "status": "success"
225
- }
283
+ #return {
284
+ # "activities": activities_data,
285
+ # "count": len(activities_data) if isinstance(activities_data, list) else 0,
286
+ # "status": "success"
287
+ #}
226
288
 
227
289
  @mcp.tool("strava://auth/save")
228
290
  async def save_tokens(tokens: dict | None = None) -> dict:
@@ -244,8 +306,24 @@ async def load_tokens() -> dict:
244
306
  return {"ok": True, "tokens": result.get("tokens"), "path": result.get("path")}
245
307
 
246
308
  @mcp.tool("strava://athlete/refresh-and-stats")
247
- async def refresh_and_get_stats(client_id: int | None = None, client_secret: str | None = None) -> dict:
248
- """Load saved refresh token, refresh access token, save it, then fetch activities."""
309
+ async def refresh_and_get_stats(
310
+ client_id: int | None = None,
311
+ client_secret: str | None = None,
312
+ after: int | None = None,
313
+ before: int | None = None,
314
+ page: int | None = None,
315
+ per_page: int | None = None
316
+ ) -> dict:
317
+ """Load saved refresh token, refresh access token, save it, then fetch activities with optional filters.
318
+
319
+ Args:
320
+ client_id: Strava client ID
321
+ client_secret: Strava client secret
322
+ after: An epoch timestamp to use for filtering activities that have taken place after a certain time
323
+ before: An epoch timestamp to use for filtering activities that have taken place before a certain time
324
+ page: The page of activities (default=1)
325
+ per_page: How many activities per page (default=30)
326
+ """
249
327
  load_result = await load_tokens()
250
328
  if not load_result.get("ok"):
251
329
  return {"error": "no saved tokens", "details": load_result}
@@ -265,8 +343,14 @@ async def refresh_and_get_stats(client_id: int | None = None, client_secret: str
265
343
  if not access_token:
266
344
  return {"error": "no access_token after refresh"}
267
345
 
268
- # Fetch activities with new token
269
- activities = await get_athlete_stats_with_token(access_token)
346
+ # Fetch activities with new token and filters
347
+ activities = await get_athlete_stats_with_token(
348
+ access_token=access_token,
349
+ after=after,
350
+ before=before,
351
+ page=page,
352
+ per_page=per_page
353
+ )
270
354
  return {"activities": activities, "tokens": refreshed}
271
355
 
272
356
  @mcp.tool("strava://session/start")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strava-activity-mcp-server
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Strava MCP server: one-time browser auth, then automatic refresh-token login
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.10
@@ -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=z8o56-FpBwpvR4fkMz4thP3jnFbUgoqyyocCSXpt0eQ,14671
4
+ strava_activity_mcp_server-0.2.6.dist-info/METADATA,sha256=a0KTpNVNGv-agc4xPgxiHNWE3TYnZ7qOhxGXqiByV_c,7665
5
+ strava_activity_mcp_server-0.2.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ strava_activity_mcp_server-0.2.6.dist-info/entry_points.txt,sha256=F6PO_DBSThhtmX2AC-tu2MIiCJkGi31LCaQJxfUzZ5g,79
7
+ strava_activity_mcp_server-0.2.6.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
8
+ strava_activity_mcp_server-0.2.6.dist-info/RECORD,,
@@ -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=0ipTrX7ydrDaATRhyvCO5wseprC96-tT2XVkXB_h3Ok,11643
4
- strava_activity_mcp_server-0.2.4.dist-info/METADATA,sha256=KoVyfCThPzgXfsaK7fGgKPjDHNoI3DSURmhY6uW_MNE,7665
5
- strava_activity_mcp_server-0.2.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- strava_activity_mcp_server-0.2.4.dist-info/entry_points.txt,sha256=F6PO_DBSThhtmX2AC-tu2MIiCJkGi31LCaQJxfUzZ5g,79
7
- strava_activity_mcp_server-0.2.4.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
8
- strava_activity_mcp_server-0.2.4.dist-info/RECORD,,