A Python-native Strava MCP server for deep activity analysis. Access the user's Strava running and fitness data.
Server has 8 well-named tools with consistent verb_noun patterns (get_*, search_*). All tools have descriptions (avg ~100 chars, within baseline 34-392). Input schemas are present and typed for all tools. However, descriptions are terse and lack WHEN/WHY guidance. Output schemas are undocumented, responses are free-text strings rather than structured objects. No error handling guidance, no parameter validation hints, no pagination support despite tools returning lists. Missing tool annotations (readOnlyHint, idempotentHint). Composition is sound (single responsibility per tool), but output formatting wastes tokens on human-readable text instead of structured JSON.
Get full details for a specific activity including splits and HR zones.
Get time-series data for an activity. Uses downsample_sec (default 60s) to reduce LLM token usage while preserving shape.
Get the athlete's Strava profile including weight and location.
Get all-time and recent running stats.
Get shoe/gear mileage — useful for knowing when to replace gear.
Get recent Strava activities with distance, time, pace, and heart rate.
All tools return free-text strings instead of structured JSON objects. LLMs must parse unstructured output, wasting tokens and increasing hallucination risk. E.g., get_recent_activities returns '\n'-joined lines; should return {activities: [{id, name, distance_mi, pace, hr, type}], total_count}.
No output schema documentation. LLMs cannot plan downstream calls or extract fields reliably. Baseline: 100% of A+ tools document return types.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Get weekly mileage, run count, and average pace for recent weeks.
Search and filter activities by type (Run, Ride), date (YYYY-MM-DD), distance, or title keyword.
Tool descriptions lack WHEN/WHY guidance. E.g., 'Get recent Strava activities...' does not explain when to call this vs search_activities, or what the LLM should do with the results. Descriptions should be 50-200 chars and answer: What? When? Why?
No tool annotations (readOnlyHint, idempotentHint). All tools are read-only but this is not declared in the schema. Agents cannot distinguish safe-to-retry tools from destructive ones.
No pagination support. search_activities and get_recent_activities return lists but lack offset/limit in response or next_cursor. Large result sets will blow context window. Baseline: paginated-result pattern requires total_count and cursor/offset.