Strava MCP 服务器
该项目用 TypeScript 实现了一个模型上下文协议 (MCP) 服务器,作为连接 Strava API 的桥梁。它将 Strava 的数据和功能公开为大型语言模型 (LLM) 可以通过 MCP 标准利用的“工具”。
特征
🏃 访问最近的活动、个人资料和统计数据。
📊 获取详细的活动流(功率、心率、节奏等)。
🗺️ 探索、查看、加星标和管理片段。
⏱️查看详细的活动和细分工作量信息。
📍 列出并查看已保存路线的详细信息。
💾 将 GPX 或 TCX 格式的路线导出到本地文件系统。
🤖 通过 MCP 实现 AI 友好的 JSON 响应。
🔧 使用 Strava API V3。
自然语言交互示例
向你的 AI 助手询问如下问题,以便与你的 Strava 数据进行交互:
近期活动和个人资料:
“显示我最近的 Strava 活动。”
“我最近三次骑行经历是怎样的?”
“获取我的 Strava 个人资料信息。”
“我的 Strava 用户名是什么?”
活动流和数据:
“获取我昨天晨跑的心率数据。”
“显示我上次骑行的功率数据。”
“我周末百公里骑行的节奏是多少?”
“获取我周四晚上锻炼的所有流数据。”
“向我展示攀登魔鬼山的海拔剖面图。”
统计数据:
“我今年在 Strava 上的跑步统计数据是什么?”
“我一共骑了多远?”
“显示我的所有游泳记录。”
具体活动:
“告诉我上次跑步的详细信息。”
“我周二的间歇训练的平均功率是多少?”
“我昨天骑 Trek 自行车上下班了吗?”
俱乐部:
“我加入了哪些 Strava 俱乐部?”
“列出我加入的俱乐部。”
段:
“列出我在科罗拉多州博尔德附近主演的片段。”
“显示我最喜欢的片段。”
“获取‘Alpe du Zwift’ 路段的详细信息。”
“金门公园附近有没有什么好的跑步路段?”
“寻找博尔德斯弗拉格斯塔夫山附近的具有挑战性的攀登路线。”
“为我加注‘攀登旗杆路’部分。”
“取消‘左手峡谷’片段的星标。”
细分领域努力:
“本月在‘阳光峡谷’环节展现我的努力。”
“列出我今年 1 月至 6 月在 Box Hill 的尝试。”
“获取我在阿尔卑斯山的私人记录的详细信息。”
路线:
“列出我保存的 Strava 路线。”
“显示我的路线的第二页。”
“我的博尔德环线路线的海拔高度是多少?”
“获取我的‘Boulder Loop’路线的描述。”
“将我的‘Boulder Loop’路线导出为 GPX 文件。”
“将我周日早上的路线保存为 TCX 文件。”
高级提示示例
以下是更高级提示的示例,用于创建专业自行车教练对您的 Strava 活动的分析:
此提示会对您最近的 Strava 活动进行个性化分析,并附上专业指导反馈和自定义可视化仪表板。
⚠️ 重要的设置顺序
为了成功与 Claude 集成,请按照以下步骤操作:
安装服务器及其依赖项
在 Claude 的配置中配置服务器
完成 Strava 身份验证流程
重新启动 Claude 以确保正确加载环境变量
跳过步骤或按顺序执行可能会导致 Claude 无法正确读取环境变量。
安装和设置
先决条件:
Node.js(建议使用 v18 或更高版本)
npm(通常随 Node.js 提供)
Strava 帐户
1. 从源头
克隆存储库:
git clone https://github.com/r-huijts/strava-mcp.git cd strava-mcp安装依赖项:
npm install构建项目:
npm run build
2.配置Claude桌面
更新您的 Claude 配置文件:
确保将/absolute/path/to/your/strava-mcp/替换为您安装的实际路径。
3. Strava 身份验证设置
setup-auth.ts脚本可让您轻松使用 Strava API 设置身份验证。请仔细遵循以下步骤:
创建 Strava API 应用程序
创建新应用程序:
输入您的应用程序详细信息(名称、网站、描述)
重要提示:将“授权回调域”设置为
localhost记下您的客户端 ID 和客户端密钥
运行安装脚本
按照提示完成身份验证流程(详细说明见下面的身份验证部分)。
4.重启克劳德
完成以上所有步骤后,重新启动 Claude Desktop 以使更改生效。这可确保:
新配置已加载
环境变量已正确读取
Strava MCP 服务器已正确初始化
🔑 环境变量
多变的 | 描述 |
STRAVA_CLIENT_ID | 您的 Strava 应用程序客户端 ID(必填) |
STRAVA_CLIENT_SECRET | 您的 Strava 应用程序客户端密钥(必需) |
STRAVA_ACCESS_TOKEN | 您的 Strava API 访问令牌(在设置过程中生成) |
STRAVA_REFRESH_TOKEN | 您的 Strava API 刷新令牌(在设置过程中生成) |
路由导出路径 | 保存导出的路线文件的绝对路径(可选) |
令牌处理
本服务器实现了令牌自动刷新功能。当初始访问令牌过期(通常为 6 小时后)时,服务器将自动使用.env中存储的刷新令牌获取新的访问令牌和刷新令牌。新的令牌会在运行的进程和.env文件中同步更新,从而确保服务器持续运行。
您只需运行一次scripts/setup-auth.ts脚本即可进行初始设置。
配置导出路径(可选)
如果您打算使用export-route-gpx或export-route-tcx工具,则需要指定一个用于保存导出文件的目录。
编辑您的.env文件并添加/更新ROUTE_EXPORT_PATH变量:
将占位符替换为所需导出目录的绝对路径。确保该目录存在并且服务器具有写入权限。
API 参考
该服务器公开以下 MCP 工具:
get-recent-activities
获取经过身份验证的用户的最近活动。
**使用时间:**当用户询问他们最近的锻炼、活动、跑步、骑行等情况时。
参数:
perPage(可选):类型:
number描述:要检索的活动数量。
默认值:30
**输出:**最近活动的格式化文本列表(姓名、ID、距离、日期)。
**错误:**丢失/无效的令牌,Strava API 错误。
get-athlete-profile
获取已验证运动员的个人资料信息。
**何时使用:**当用户询问其个人资料详细信息、用户名、位置、体重、高级状态等时。
**参数:**无
**输出:**带有配置文件详细信息的格式化文本字符串。
**错误:**丢失/无效的令牌,Strava API 错误。
get-athlete-stats
获取已认证运动员的活动统计数据(最近、年初至今、所有时间)。
**何时使用:**当用户询问他们的总体统计数据、跑步/骑行/游泳的总数、个人记录(最长骑行、最大爬升)时。
**参数:**无
**输出:**格式化的统计数据文本摘要,尊重用户的测量偏好。
**错误:**丢失/无效的令牌,Strava API 错误。
get-activity-details
使用特定活动的 ID 获取有关该活动的详细信息。
**何时使用:**当用户询问有关由其 ID 标识的特定活动的详细信息时。
参数:
activityId(必填):类型:
number描述:活动的唯一标识符。
**输出:**格式化的文本字符串,包含详细的活动信息(类型、日期、距离、时间、速度、心率、功率、装备等),尊重用户的测量偏好。
**错误:**丢失/无效的令牌、无效的
activityId、Strava API 错误。
list-athlete-clubs
列出已认证运动员所属的俱乐部。
**使用时机:**当用户询问自己加入的俱乐部时。
**参数:**无
**输出:**俱乐部的格式化文本列表(名称、ID、运动、会员、位置)。
**错误:**丢失/无效的令牌,Strava API 错误。
list-starred-segments
列出已认证运动员出演的片段。
**何时使用:**当用户询问他们加星标或喜欢的片段时。
**参数:**无
**输出:**带星号的片段的格式化文本列表(名称、ID、类型、距离、等级、位置)。
**错误:**丢失/无效的令牌,Strava API 错误。
get-segment
使用 ID 获取有关特定段的详细信息。
**何时使用:**当用户询问有关由其 ID 标识的特定段的详细信息时。
参数:
segmentId(必填):类型:
number描述:段的唯一标识符。
**输出:**格式化的文本字符串,包含详细的段信息(距离、等级、海拔、位置、星级、努力程度等),尊重用户的测量偏好。
**错误:**丢失/无效的令牌、无效的
segmentId、Strava API 错误。
explore-segments
在给定的地理区域(边界框)内搜索热门片段。
**何时使用:**当用户想要查找或发现特定地理区域内的路段时,可选择按活动类型或攀登类别进行筛选。
参数:
bounds(必需):类型:
string描述:以逗号分隔:
south_west_lat,south_west_lng,north_east_lat,north_east_lng。
activityType(可选):类型:
string("running"或"riding")描述:按活动类型过滤。
minCat(可选):类型:
number(0-5)描述:最低爬坡等级。要求
activityType: 'riding'。
maxCat(可选):类型:
number(0-5)描述:最大爬坡等级。需要
activityType: 'riding'。
**输出:**找到的段的格式化文本列表(名称、ID、爬升类别、距离、等级、海拔)。
**错误:**缺失/无效的令牌、无效的
bounds格式、无效的过滤器组合、Strava API 错误。
star-segment
为已认证运动员的特定片段添加或取消星标。
**何时使用:**当用户明确要求为通过其 ID 标识的特定片段加星标、收藏、取消星标或取消收藏时。
参数:
segmentId(必填):类型:
number描述:段的唯一标识符。
starred(必填):类型:
boolean描述:
true则为星号,false则为取消星号。
**输出:**确认操作和片段的新加星状态的成功消息。
**错误:**丢失/无效的令牌、无效的
segmentId、Strava API 错误(例如,未找到段、速率限制)。
get-segment-effort
使用 ID 获取有关特定细分工作的详细信息。
**何时使用:**当用户询问有关由其 ID 标识的特定细分工作的详细信息时。
参数:
effortId(必填):类型:
number描述:分段工作的唯一标识符。
**输出:**带有详细工作量信息(段名称、活动 ID、时间、距离、HR、功率、排名等)的格式化文本字符串。
**错误:**丢失/无效的令牌、无效的
effortId、Strava API 错误。
list-segment-efforts
列出经过验证的运动员在特定赛段上的努力,可选择按日期进行过滤。
**何时使用:**当用户要求列出他们在特定细分市场(可能在某个日期范围内)的努力或尝试时。
参数:
segmentId(必填):类型:
number描述:段的 ID。
startDateLocal(可选):类型:
string(ISO 8601 格式)描述:过滤在此日期时间之后开始的工作。
endDateLocal(可选):类型:
string(ISO 8601 格式)描述:过滤在此日期时间之前结束的工作。
perPage(可选):类型:
number描述:每页的结果数。
默认值:30
**输出:**匹配的细分工作的格式化文本列表。
**错误:**丢失/无效的令牌、无效的
segmentId、无效的日期格式、Strava API 错误。
list-athlete-routes
列出经过验证的运动员创建的路线。
**何时使用:**当用户要求查看他们创建或保存的路线时。
参数:
page(可选):类型:
number描述:分页的页码。
perPage(可选):类型:
number描述:每页的路线数。
默认值:30
**输出:**路线的格式化文本列表(名称、ID、类型、距离、海拔、日期)。
**错误:**丢失/无效令牌,Strava API 错误。
get-route
使用特定路线的 ID 获取其详细信息。
**何时使用:**当用户询问有关由其 ID 标识的特定路线的详细信息时。
参数:
routeId(必填):类型:
number描述:路线的唯一标识符。
**输出:**带有路线详细信息(名称、ID、类型、距离、海拔、预计时间、描述、路段数)的格式化文本字符串。
**错误:**丢失/无效的令牌、无效的
routeId、Strava API 错误。
export-route-gpx
以 GPX 格式导出特定路线并将其保存在本地。
**何时使用:**当用户明确要求将特定路线导出或保存为 GPX 文件时。
**前提条件:**服务器上必须正确配置
ROUTE_EXPORT_PATH环境变量。参数:
routeId(必填):类型:
number描述:路线的唯一标识符。
**输出:**指示保存位置的成功消息,或错误消息。
**错误:**丢失/无效的令牌、丢失/无效的
ROUTE_EXPORT_PATH、文件系统错误(权限、磁盘空间)、无效的routeId、Strava API 错误。
export-route-tcx
将特定路线以 TCX 格式导出并保存在本地。
**何时使用:**当用户明确要求将特定路线导出或保存为 TCX 文件时。
**前提条件:**服务器上必须正确配置
ROUTE_EXPORT_PATH环境变量。参数:
routeId(必填):类型:
number描述:路线的唯一标识符。
**输出:**指示保存位置的成功消息,或错误消息。
**错误:**丢失/无效的令牌、丢失/无效的
ROUTE_EXPORT_PATH、文件系统错误(权限、磁盘空间)、无效的routeId、Strava API 错误。
get-activity-streams
从 Strava 活动中检索详细的时间序列数据流,非常适合分析锻炼指标、可视化路线或执行详细的活动分析。
**何时使用:**当您需要某项活动的详细时间序列数据时:
通过心率区分析锻炼强度
计算骑行活动的功率指标
使用 GPS 坐标可视化路线数据
分析步速和海拔变化
详细细分分析
参数:
id(必填):类型:
number | string描述:用于获取流的 Strava 活动标识符
types(可选):类型:
array默认值:
['time', 'distance', 'heartrate', 'cadence', 'watts']可用类型:
time:从开始算起的时间(秒)distance:距起点的距离(以米为单位)latlng:[纬度,经度] 对的数组altitude:海拔(米)velocity_smooth:平滑速度(米/秒)heartrate:心率(每分钟心跳数)cadence:每分钟转数watts:输出功率(瓦特)temp:摄氏度moving:布尔值,指示是否移动grade_smooth:道路等级百分比
resolution(可选):类型:
string值:
'low'(~100 分)、'medium'(~1000 分)、'high'(~10000 分)描述:数据分辨率/密度
series_type(可选):类型:
string值:
'time'或'distance'默认值:
'distance'描述:数据点索引的基本系列类型
page(可选):类型:
number默认值:1
描述:分页结果的页码
points_per_page(可选):类型:
number默认值:100
特殊值:
-1返回拆分成多条消息的所有数据点描述:每页数据点的数量
输出格式:
元数据:
可用的流类型
总数据点
分辨率和系列类型
分页信息(当前页,总页数)
统计数据(如适用):
心率:最大、最小、平均
功率:最大、平均、标准化功率
速度:最大速度和平均速度(公里/小时)
流数据:
每个请求流的格式化时间序列数据
人类可读的格式(例如格式化的时间、速度的 km/h)
一致的数值精度
标记数据点
示例请求:
{ "id": 12345678, "types": ["time", "heartrate", "watts", "velocity_smooth", "cadence"], "resolution": "high", "points_per_page": 100, "page": 1 }特殊功能:
大型数据集的智能分页
完整数据检索模式(points_per_page = -1)
丰富的统计数据和元数据
格式化输出,供人类和 LLM 使用
自动单位转换
笔记:
需要活动:阅读范围
并非所有活动都适用所有流
较旧的活动可能数据有限
大型活动会自动分页
流可用性取决于录制设备和活动类型
错误:
令牌缺失/无效
活动 ID 无效
权限不足
不可用的流类型
分页参数无效
get-activity-laps
检索特定 Strava 活动记录的圈数。
何时使用:
分析活动不同部分(圈)的表现变化。
比较单圈时间、速度、心率或功率输出。
了解活动的结构(例如间歇训练)。
参数:
id(必填):类型:
number | string描述:Strava 活动的唯一标识符。
**输出格式:**详细描述每一圈的文本摘要,包括:
圈数索引
圈数名称(如有)
已用时间(格式为 HH:MM:SS)
移动时间(格式为 HH:MM:SS)
距离(公里)
平均速度(公里/小时)
最大速度(公里/小时)
总海拔高度(米)
平均心率(如有,以 bpm 为单位)
最大心率(如有,以 bpm 为单位)
平均节奏(如有,以 rpm 为单位)
平均瓦数(如有,以瓦为单位)
示例请求:
{ "id": 1234567890 }响应片段示例:
Activity Laps Summary (ID: 1234567890): Lap 1: Warmup Lap Time: 15:02 (Moving: 14:35) Distance: 5.01 km Avg Speed: 20.82 km/h Max Speed: 35.50 km/h Elevation Gain: 50.2 m Avg HR: 135.5 bpm Max HR: 150 bpm Avg Cadence: 85.0 rpm Lap 2: Interval 1 Time: 05:15 (Moving: 05:10) Distance: 2.50 km Avg Speed: 29.03 km/h Max Speed: 42.10 km/h Elevation Gain: 10.1 m Avg HR: 168.2 bpm Max HR: 175 bpm Avg Cadence: 92.1 rpm Avg Power: 280.5 W (Sensor) ...笔记:
需要
activity:read公共/关注者活动的范围,activity:read_all私人活动的范围。圈数数据的可用性取决于记录设备和活动类型(例如,手动活动可能没有圈数)。
错误:
令牌缺失/无效
活动 ID 无效
权限不足
未找到活动
get-athlete-zones
检索经过验证的运动员配置的心率和功率区。
**何时使用:**当用户询问他们的心率区、功率区或训练区设置时。
**参数:**无
**输出格式:**返回两个文本块:
详细说明已配置区域的格式化摘要:
心率区:自定义状态、区域范围、时间分布(如果可用)
功率区:区域范围、时间分布(如果可用)
Strava API 返回的完整原始 JSON 数据。
响应片段示例(摘要):
**Athlete Zones:** ❤️ **Heart Rate Zones** Custom Zones: No Zone 1: 0 - 115 bpm Zone 2: 115 - 145 bpm Zone 3: 145 - 165 bpm Zone 4: 165 - 180 bpm Zone 5: 180+ bpm ⚡ **Power Zones** Zone 1: 0 - 150 W Zone 2: 151 - 210 W Zone 3: 211 - 250 W Zone 4: 251 - 300 W Zone 5: 301 - 350 W Zone 6: 351 - 420 W Zone 7: 421+ W Time Distribution: - 0-50: 0:24:58 - 50-100: 0:01:02 ... - 450-∞: 0:05:43笔记:
需要配置
profile:read_all范围。区域可能并未针对所有运动员进行配置。
错误:
令牌缺失/无效
权限不足(缺少
profile:read_all范围 - 403 错误)需要订阅(如果 Strava 更改 API 访问权限,则可能需要订阅)
贡献
欢迎贡献代码!欢迎提交 Pull 请求。
执照
本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。(假设采用 MIT 许可证,如有不同,请更新)
Related Resources
Related MCP Servers
- AsecurityAlicenseAqualityA Model Context Protocol server that provides language models with access to Strava API data, allowing them to query and analyze athlete activities from Strava.Last updated -417MIT License
- AsecurityAlicenseAqualityA TypeScript-based server that enables interaction with Jira, providing tools to execute JQL queries, manage tickets, list projects and statuses through natural language.Last updated -1125MIT License
- -securityAlicense-qualityA Model Context Protocol server that enables language models to interact with Strava data, including activities, athlete statistics, routes, achievements, and social features.Last updated -3MIT License
- AsecurityAlicenseAqualityA Model Context Protocol server that enables users to access Strava fitness data, including user activities, activity details, segments, and leaderboards through a structured API interface.Last updated -34MIT License