Skip to main content
Glama

list-starred-segments

Retrieve starred segments for the authenticated user to track and analyze preferred running or cycling routes via the Strava MCP Server.

Instructions

Lists the segments starred by the authenticated athlete.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The execute handler implementing the tool's core logic: token validation, fetching athlete data and starred segments, formatting output with measurement preferences, handling errors.
    execute: async () => { const token = process.env.STRAVA_ACCESS_TOKEN; if (!token || token === 'YOUR_STRAVA_ACCESS_TOKEN_HERE') { console.error("Missing or placeholder STRAVA_ACCESS_TOKEN in .env"); return { content: [{ type: "text" as const, text: "❌ Configuration Error: STRAVA_ACCESS_TOKEN is missing or not set in the .env file." }], isError: true, }; } try { console.error("Fetching starred segments..."); // Need athlete measurement preference for formatting distance const athlete = await getAuthenticatedAthlete(token); // Use renamed import const segments = await fetchSegments(token); console.error(`Successfully fetched ${segments?.length ?? 0} starred segments.`); if (!segments || segments.length === 0) { return { content: [{ type: "text" as const, text: " MNo starred segments found." }] }; } const distanceFactor = athlete.measurement_preference === 'feet' ? 0.000621371 : 0.001; const distanceUnit = athlete.measurement_preference === 'feet' ? 'mi' : 'km'; // Format the segments into a text response const segmentText = segments.map(segment => { const location = [segment.city, segment.state, segment.country].filter(Boolean).join(", ") || 'N/A'; const distance = (segment.distance * distanceFactor).toFixed(2); return ` ⭐ **${segment.name}** (ID: ${segment.id}) - Activity Type: ${segment.activity_type} - Distance: ${distance} ${distanceUnit} - Avg Grade: ${segment.average_grade}% - Location: ${location} - Private: ${segment.private ? 'Yes' : 'No'} `.trim(); }).join("\n---\n"); const responseText = `**Your Starred Segments:**\n\n${segmentText}`; return { content: [{ type: "text" as const, text: responseText }] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "An unknown error occurred"; console.error("Error in list-starred-segments tool:", errorMessage); return { content: [{ type: "text" as const, text: `❌ API Error: ${errorMessage}` }], isError: true, }; } }
  • src/server.ts:80-85 (registration)
    Registers the 'list-starred-segments' tool on the MCP server by calling server.tool with the imported tool object's name, description, empty input schema object, and execute function.
    server.tool( listStarredSegments.name, listStarredSegments.description, {}, listStarredSegments.execute );
  • Tool object definition specifying the name, description, and inputSchema as undefined (tool takes no parameters).
    export const listStarredSegments = { name: "list-starred-segments", description: "Lists the segments starred by the authenticated athlete.", // No input schema needed inputSchema: undefined,
  • Strava API client helper function 'listStarredSegments' that fetches starred segments from '/segments/starred' endpoint, validates response with Zod schema, handles authentication errors with token refresh.
    export async function listStarredSegments(accessToken: string): Promise<StravaSegment[]> { if (!accessToken) { throw new Error("Strava access token is required."); } try { // Strava API uses page/per_page but often defaults reasonably for lists like this. // Add pagination parameters if needed later. const response = await stravaApi.get<unknown>("segments/starred", { headers: { Authorization: `Bearer ${accessToken}` } }); const validationResult = StravaSegmentsResponseSchema.safeParse(response.data); if (!validationResult.success) { console.error("Strava API validation failed (listStarredSegments):", validationResult.error); throw new Error(`Invalid data format received from Strava API: ${validationResult.error.message}`); } return validationResult.data; } catch (error) { return await handleApiError<StravaSegment[]>(error, 'listStarredSegments', async () => { // Use new token from environment after refresh const newToken = process.env.STRAVA_ACCESS_TOKEN!; return listStarredSegments(newToken); }); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/r-huijts/strava-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server