feat: standardize on ISO 8601 for dates, add utility functions, and document design decisions.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import json
|
||||
from mcp.server.fastmcp import FastMCP, Context
|
||||
from mcp.types import TextContent
|
||||
from mcp.types import TextContent, Annotations
|
||||
from strava_mcp_server.strava_client import StravaClient
|
||||
from strava_mcp_server.utils import parse_iso_to_unix, format_date_iso, format_date_human
|
||||
|
||||
def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
@mcp.tool()
|
||||
@@ -9,16 +10,15 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
ctx: Context,
|
||||
limit: int = 10,
|
||||
page: int = 1,
|
||||
before: int | None = None,
|
||||
after: int | None = None,
|
||||
before: str | None = None,
|
||||
after: str | None = None,
|
||||
) -> list[TextContent]:
|
||||
"""
|
||||
List recent Strava activities for the authenticated user.
|
||||
:param limit: Number of activities to return per page (default 10, max 200).
|
||||
:param page: Page number for pagination (default 1).
|
||||
:param before: Unix timestamp — only return activities before this time.
|
||||
:param after: Unix timestamp — only return activities after this time.
|
||||
Example: 1704067200 = 2024-01-01 00:00:00 UTC.
|
||||
:param before: ISO 8601 date string (e.g., '2024-05-01T00:00:00Z') — only return activities before this time.
|
||||
:param after: ISO 8601 date string (e.g., '2024-04-01T00:00:00Z') — only return activities after this time.
|
||||
"""
|
||||
try:
|
||||
await ctx.info(f"Fetching activities (Page {page}, Limit {limit})...")
|
||||
@@ -26,27 +26,19 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
activities = await strava.list_activities(
|
||||
limit=min(limit, 200),
|
||||
page=page,
|
||||
before=before,
|
||||
after=after,
|
||||
before=parse_iso_to_unix(before),
|
||||
after=parse_iso_to_unix(after),
|
||||
)
|
||||
|
||||
from datetime import datetime
|
||||
def format_date(d_str):
|
||||
if not d_str:
|
||||
return "N/A"
|
||||
try:
|
||||
d = datetime.fromisoformat(d_str.replace('Z', '+00:00'))
|
||||
return f"{d.day:02d}.{d.month:02d}.{d.year} {d.hour:02d}:{d.minute:02d}"
|
||||
except Exception:
|
||||
return d_str
|
||||
|
||||
essential_data = []
|
||||
for a in activities:
|
||||
start_date_raw = a.get("start_date")
|
||||
essential_data.append({
|
||||
"id": a["id"],
|
||||
"name": a["name"],
|
||||
"sport_type": a.get("sport_type") or a.get("type"),
|
||||
"start_date": format_date(a.get("start_date")),
|
||||
"start_date": format_date_iso(start_date_raw),
|
||||
"start_date_local": format_date_human(start_date_raw),
|
||||
"distance": f"{a.get('distance', 0) / 1000:.2f} km",
|
||||
"moving_time": f"{a.get('moving_time', 0) / 60:.1f} min",
|
||||
"total_elevation_gain": f"{a.get('total_elevation_gain', 0):.0f} m",
|
||||
@@ -62,13 +54,18 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
markdown_summary += "|-------|-------|------|---------|------|------------|------|\n"
|
||||
for a in essential_data:
|
||||
hr = f"{a['average_heartrate']:.0f} bpm" if a['average_heartrate'] else "-"
|
||||
markdown_summary += f"| {a['start_date']} | {a['sport_type']} | {a['name']} | {a['distance']} | {a['moving_time']} | {a['total_elevation_gain']} | {hr} |\n"
|
||||
markdown_summary += f"| {a['start_date_local']} | {a['sport_type']} | {a['name']} | {a['distance']} | {a['moving_time']} | {a['total_elevation_gain']} | {hr} |\n"
|
||||
|
||||
return [
|
||||
TextContent(type="text", text=markdown_summary.strip()),
|
||||
TextContent(
|
||||
type="text",
|
||||
text=f"Raw Data for Analysis: {json.dumps(essential_data, indent=2)}"
|
||||
text=markdown_summary.strip(),
|
||||
annotations=Annotations(audience=["user"])
|
||||
),
|
||||
TextContent(
|
||||
type="text",
|
||||
text=json.dumps(essential_data, indent=2),
|
||||
annotations=Annotations(audience=["assistant"])
|
||||
)
|
||||
]
|
||||
except Exception as e:
|
||||
@@ -112,7 +109,7 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
"id": c.get("id"),
|
||||
"text": c.get("text"),
|
||||
"athlete": f"{c.get('athlete', {}).get('firstname')} {c.get('athlete', {}).get('lastname')}",
|
||||
"created_at": c.get("created_at"),
|
||||
"created_at": format_date_iso(c.get("created_at")),
|
||||
}
|
||||
for c in comments
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user