Skip to main content
Glama

get-segment-effort

Fetch detailed information about a specific Strava segment effort using its unique identifier to analyze performance data.

Instructions

Fetches detailed information about a specific segment effort using its ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
effortIdYesThe unique identifier of the segment effort to fetch.

Implementation Reference

  • The core handler for the 'get-segment-effort' tool, defining the tool object with name, description, input schema, and the execute function that fetches the effort data using fetchSegmentEffort and formats it for output.
    export const getSegmentEffortTool = { name: "get-segment-effort", description: "Fetches detailed information about a specific segment effort using its ID.", inputSchema: GetSegmentEffortInputSchema, execute: async ({ effortId }: GetSegmentEffortInput) => { const token = process.env.STRAVA_ACCESS_TOKEN; if (!token) { console.error("Missing STRAVA_ACCESS_TOKEN environment variable."); return { content: [{ type: "text" as const, text: "Configuration error: Missing Strava access token." }], isError: true }; } try { console.error(`Fetching details for segment effort ID: ${effortId}...`); // Removed getAuthenticatedAthlete call const effort = await fetchSegmentEffort(token, effortId); const effortDetailsText = formatSegmentEffort(effort); // Use metric formatter console.error(`Successfully fetched details for effort: ${effort.name}`); return { content: [{ type: "text" as const, text: effortDetailsText }] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`Error fetching segment effort ${effortId}: ${errorMessage}`); let userFriendlyMessage; if (errorMessage.startsWith("SUBSCRIPTION_REQUIRED:")) { userFriendlyMessage = `🔒 Accessing this segment effort (ID: ${effortId}) requires a Strava subscription. Please check your subscription status.`; } else if (errorMessage.includes("Record Not Found") || errorMessage.includes("404")) { userFriendlyMessage = `Segment effort with ID ${effortId} not found.`; } else { userFriendlyMessage = `An unexpected error occurred while fetching segment effort ${effortId}. Details: ${errorMessage}`; } return { content: [{ type: "text" as const, text: `❌ ${userFriendlyMessage}` }], isError: true }; } } };
  • Zod schema defining the input for the tool: effortId (number).
    const GetSegmentEffortInputSchema = z.object({ effortId: z.number().int().positive().describe("The unique identifier of the segment effort to fetch.") });
  • src/server.ts:105-110 (registration)
    Registration of the get-segment-effort tool on the MCP server using server.tool().
    server.tool( getSegmentEffortTool.name, getSegmentEffortTool.description, getSegmentEffortTool.inputSchema?.shape ?? {}, getSegmentEffortTool.execute );
  • Helper function to format the segment effort details into a readable string, used in the handler.
    function formatSegmentEffort(effort: StravaDetailedSegmentEffort): string { const movingTime = formatDuration(effort.moving_time); const elapsedTime = formatDuration(effort.elapsed_time); const distance = formatDistance(effort.distance); // Remove speed/pace calculations as fields are not available on effort object // const avgSpeed = formatSpeed(effort.average_speed); // const maxSpeed = formatSpeed(effort.max_speed); // const avgPace = formatPace(effort.average_speed); let details = `⏱️ **Segment Effort: ${effort.name}** (ID: ${effort.id})\n`; details += ` - Activity ID: ${effort.activity.id}, Athlete ID: ${effort.athlete.id}\n`; details += ` - Segment ID: ${effort.segment.id}\n`; details += ` - Date: ${new Date(effort.start_date_local).toLocaleString()}\n`; details += ` - Moving Time: ${movingTime}, Elapsed Time: ${elapsedTime}\n`; if (effort.distance !== undefined) details += ` - Distance: ${distance}\n`; // Remove speed/pace display lines // if (effort.average_speed !== undefined) { ... } // if (effort.max_speed !== undefined) { ... } if (effort.average_cadence !== undefined && effort.average_cadence !== null) details += ` - Avg Cadence: ${effort.average_cadence.toFixed(1)}\n`; if (effort.average_watts !== undefined && effort.average_watts !== null) details += ` - Avg Watts: ${effort.average_watts.toFixed(1)}\n`; if (effort.average_heartrate !== undefined && effort.average_heartrate !== null) details += ` - Avg Heart Rate: ${effort.average_heartrate.toFixed(1)} bpm\n`; if (effort.max_heartrate !== undefined && effort.max_heartrate !== null) details += ` - Max Heart Rate: ${effort.max_heartrate.toFixed(0)} bpm\n`; if (effort.kom_rank !== null) details += ` - KOM Rank: ${effort.kom_rank}\n`; if (effort.pr_rank !== null) details += ` - PR Rank: ${effort.pr_rank}\n`; details += ` - Hidden: ${effort.hidden ? 'Yes' : 'No'}\n`; return details; }
  • Underlying Strava API client function that performs the actual HTTP request to fetch segment effort details, imported as fetchSegmentEffort.
    export async function getSegmentEffort(accessToken: string, effortId: number): Promise<StravaDetailedSegmentEffort> { if (!accessToken) { throw new Error("Strava access token is required."); } if (!effortId) { throw new Error("Segment Effort ID is required to fetch details."); } try { const response = await stravaApi.get<unknown>(`segment_efforts/${effortId}`, { headers: { Authorization: `Bearer ${accessToken}` } }); const validationResult = DetailedSegmentEffortSchema.safeParse(response.data); if (!validationResult.success) { console.error(`Strava API validation failed (getSegmentEffort: ${effortId}):`, validationResult.error); throw new Error(`Invalid data format received from Strava API: ${validationResult.error.message}`); } return validationResult.data; } catch (error) { return await handleApiError<StravaDetailedSegmentEffort>(error, `getSegmentEffort for ID ${effortId}`, async () => { // Use new token from environment after refresh const newToken = process.env.STRAVA_ACCESS_TOKEN!; return getSegmentEffort(newToken, effortId); }); } }

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