Initial commit: Modularized Strava MCP Server with UV and Hatchling
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from strava_mcp_server.strava_client import StravaClient
|
||||
|
||||
def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
@mcp.tool()
|
||||
async def list_athlete_clubs():
|
||||
"""
|
||||
List clubs that the authenticated athlete belongs to.
|
||||
Returns club name, sport type, member count, and city.
|
||||
"""
|
||||
try:
|
||||
clubs = await strava.get_athlete_clubs()
|
||||
return [
|
||||
{
|
||||
"id": c.get("id"),
|
||||
"name": c.get("name"),
|
||||
"sport_type": c.get("sport_type"),
|
||||
"city": c.get("city"),
|
||||
"country": c.get("country"),
|
||||
"member_count": c.get("member_count"),
|
||||
"private": c.get("private", False),
|
||||
}
|
||||
for c in clubs
|
||||
]
|
||||
except Exception as e:
|
||||
return f"Error fetching clubs: {str(e)}"
|
||||
|
||||
@mcp.tool()
|
||||
async def get_club(club_id: int):
|
||||
"""
|
||||
Get detailed information about a specific Strava club.
|
||||
:param club_id: The numeric ID of the club.
|
||||
"""
|
||||
try:
|
||||
return await strava.get_club(club_id)
|
||||
except Exception as e:
|
||||
return f"Error fetching club: {str(e)}"
|
||||
|
||||
@mcp.tool()
|
||||
async def get_club_activities(club_id: int, limit: int = 30):
|
||||
"""
|
||||
List recent activities uploaded by members of a specific club.
|
||||
:param club_id: The numeric ID of the club.
|
||||
:param limit: Number of activities to return (default 30).
|
||||
"""
|
||||
try:
|
||||
activities = await strava.get_club_activities(club_id, per_page=limit)
|
||||
return [
|
||||
{
|
||||
"name": a.get("name"),
|
||||
"sport_type": a.get("sport_type") or a.get("type"),
|
||||
"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",
|
||||
"athlete": f"{a.get('athlete', {}).get('firstname')} {a.get('athlete', {}).get('lastname')}",
|
||||
}
|
||||
for a in activities
|
||||
]
|
||||
except Exception as e:
|
||||
return f"Error fetching club activities: {str(e)}"
|
||||
|
||||
@mcp.tool()
|
||||
async def get_club_members(club_id: int, limit: int = 30):
|
||||
"""
|
||||
List members of a specific Strava club.
|
||||
:param club_id: The numeric ID of the club.
|
||||
:param limit: Number of members to return (default 30).
|
||||
"""
|
||||
try:
|
||||
members = await strava.get_club_members(club_id, per_page=limit)
|
||||
return [
|
||||
{
|
||||
"id": m.get("id"),
|
||||
"name": f"{m.get('firstname')} {m.get('lastname')}",
|
||||
"city": m.get("city"),
|
||||
"country": m.get("country"),
|
||||
}
|
||||
for m in members
|
||||
]
|
||||
except Exception as e:
|
||||
return f"Error fetching club members: {str(e)}"
|
||||
Reference in New Issue
Block a user