Strava MCP Server
一个 TypeScript 服务器,充当 Strava API 的桥梁,使大型语言模型 (LLM) 能够通过自然语言交互访问用户的活动、路线、路段和运动员数据。 Or, a slightly more formal translation: 一个 TypeScript 服务器,作为连接 Strava API 的桥梁,从而使大型语言模型 (LLM) 能够通过自然语言交互来访问用户的活动、路线、路段以及运动员数据。
r-huijts
README
Strava MCP 服务器
本项目使用 TypeScript 实现了一个模型上下文协议 (MCP) 服务器,它充当 Strava API 的桥梁。它将 Strava 数据和功能作为“工具”公开,大型语言模型 (LLM) 可以通过 MCP 标准利用这些工具。
自然语言交互示例
向您的 AI 助手提出如下问题,以与您的 Strava 数据进行交互:
最近活动和个人资料:
- “显示我最近的 Strava 活动。”
- “我最近 3 次骑行是什么?”
- “获取我的 Strava 个人资料信息。”
- “我的 Strava 用户名是什么?”
统计:
- “我在 Strava 上今年的跑步统计数据是什么?”
- “我总共骑了多远?”
- “显示我所有的游泳总数。”
特定活动:
- “给我上次跑步的详细信息(活动 ID 12345)。”
- “活动 987654321 的平均功率是多少?”
- “我是否在活动 11223344 中使用了我的 Trek 自行车?”
俱乐部:
- “我加入了哪些 Strava 俱乐部?”
- “列出我加入的俱乐部。”
路段:
- “列出我在科罗拉多州博尔德附近标记的路段。”
- “显示我最喜欢的路段。”
- “获取 'Alpe du Zwift' 路段的详细信息(ID 123456)。”
- “金门公园附近有什么好的跑步路段吗?使用边界 37.76,-122.51,37.78,-122.45。”
- “查找坐标 39.9,-105.3,40.1,-105.1 附近的 Cat 1 或 HC 爬坡。”
- “为我标记 'Flagstaff Road Climb' 路段(ID 654321)。”
- “取消标记路段 112233。”
路段成绩:
- “显示我本月在 'Sunshine Canyon' 路段(ID 987654)上的成绩。”
- “列出我在 2023-01-01 到 2023-06-30 期间在路段 123123 上的尝试。”
- “获取我的 PR 成绩的详细信息(成绩 ID 555666777)。”
路线:
- “列出我保存的 Strava 路线。”
- “显示我的路线的第二页。”
- “路线 112233 的海拔增益是多少?”
- “获取我的 'Boulder Loop' 路线的描述(ID 7654321)。”
- “将我的 'Boulder Loop' 路线(ID 7654321)导出为 GPX 文件。”
- “将路线 998877 保存为 TCX 文件。”
特性
- 🏃 访问最近的活动、个人资料和统计数据。
- 🗺️ 探索、查看、标记和管理路段。
- ⏱️ 查看详细的活动和路段成绩信息。
- 📍 列出并查看保存路线的详细信息。
- 💾 以 GPX 或 TCX 格式将路线导出到本地文件系统。
- 🤖 通过 MCP 提供 AI 友好的 JSON 响应。
- 🔧 使用 Strava API V3。
安装和设置
-
先决条件:
- Node.js(建议 v18 或更高版本)
- npm(通常随 Node.js 一起提供)
- 一个 Strava 帐户
-
克隆存储库:
git clone <repository_url> strava-mcp cd strava-mcp
(将
<repository_url>
替换为实际 URL) -
安装依赖项:
npm install
-
Strava API 应用程序设置:
- 转到您的 Strava API 设置:https://www.strava.com/settings/api
- 创建一个新的 API 应用程序(如果您还没有)。
- 至关重要: 在“授权回调域”下,输入
localhost
。 - 记下您的应用程序的 客户端 ID 和 客户端密钥。您很快就需要它们。
- 保持默认应用程序设置不变,除非您有特定需求。
-
使用设置脚本生成 API 令牌:
-
本项目包含一个脚本,用于处理 Strava OAuth 流程并获取必要的 API 令牌。
-
运行设置脚本:
npx ts-node scripts/setup-auth.ts
-
按照提示操作:
- 该脚本将首先检查您的
.env
文件(如果不存在则创建它)以查找您的STRAVA_CLIENT_ID
和STRAVA_CLIENT_SECRET
。 - 如果在
.env
中未找到,它将提示您输入从 Strava API 设置页面获得的客户端 ID 和客户端密钥。 - 然后它将显示一个 Strava 授权 URL。复制此 URL。
- 将 URL 粘贴到您的 Web 浏览器中并导航到它。
- 系统将要求您授权您的应用程序访问您的 Strava 数据,并具有所需的范围 (
profile:read_all
,activity:read_all
)。单击 授权。 - 授权后,Strava 会将您的浏览器重定向到
localhost
URL(例如,http://localhost/?state=&code=SOME_LONG_CODE&scope=read,activity:read_all,profile:read_all
)。此页面可能会显示“无法访问此站点”错误,这是 预期且正常的,因为您没有在localhost
上运行 Web 服务器。 - 重要: 查看浏览器地址栏中的 URL。复制
code
参数的值。它将是一长串字母和数字(例如,上面示例中的SOME_LONG_CODE
)。 - 返回到运行脚本的终端,并在提示时粘贴此 授权代码。
- 该脚本会将此代码交换为 访问令牌 和 刷新令牌。
- 它会询问您是否要将这些令牌保存到您的
.env
文件中。键入yes
或y
并按 Enter 键。
- 该脚本将首先检查您的
-
您的
.env
文件现在应包含:STRAVA_CLIENT_ID=YOUR_CLIENT_ID STRAVA_CLIENT_SECRET=YOUR_CLIENT_SECRET STRAVA_ACCESS_TOKEN=GENERATED_ACCESS_TOKEN STRAVA_REFRESH_TOKEN=GENERATED_REFRESH_TOKEN
-
-
配置导出路径(可选):
- 如果您打算使用
export-route-gpx
或export-route-tcx
工具,则需要指定一个用于保存导出文件的目录。 - 编辑您的
.env
文件并添加/更新ROUTE_EXPORT_PATH
变量:# 可选:定义一个*绝对*路径,用于保存导出的路线文件 (GPX/TCX) # 确保此目录存在并且服务器进程具有写入权限。 # 示例:ROUTE_EXPORT_PATH=/Users/your_username/strava-exports ROUTE_EXPORT_PATH=
- 将占位符替换为您所需导出目录的绝对路径。确保该目录存在并且服务器具有写入权限。
- 如果您打算使用
-
构建项目:
npm run build
-
运行服务器:
npm start
服务器将通过 Stdio 连接并将状态消息记录到 stderr。
-
配置 Claude Desktop(或其他 MCP 客户端):
-
要允许 MCP 客户端(如 Claude Desktop)连接到您本地运行的服务器,您需要更新其配置。
-
对于 Claude Desktop,找到配置文件(例如,macOS 上的
~/Library/Application Support/Claude/claude_desktop_config.json
)。 -
添加或更新
mcpServers
部分:{ "mcpServers": { "strava-mcp-local": { "command": "node", "args": [ "/absolute/path/to/your/strava-mcp/dist/server.js" ], // 环境变量由服务器从 .env 文件中读取, // 因此通常不需要在此处设置它们,除非要覆盖。 } } }
-
重要: 将
/absolute/path/to/your/strava-mcp/
替换为您克隆strava-mcp
存储库的实际完整路径。 -
确保
command
是node
并且args
指向编译后的dist/server.js
文件。 -
重新启动您的 MCP 客户端以使更改生效。
-
使用示例
LLM 助手(如 Claude)可以使用此服务器提供的工具,基于自然语言提示。助手通常会识别正确的工具并从用户的请求中提取必要的参数。
- 用户: “显示我最近 5 个活动。”
- LLM 操作: 调用
get-recent-activities
,其中perPage: 5
。
- LLM 操作: 调用
- 用户: “活动 987654321 的平均心率是多少?”
- LLM 操作: 调用
get-activity-details
,其中activityId: 987654321
。(然后 LLM 将解析响应以回答特定问题)。
- LLM 操作: 调用
- 用户: “查找 40.01,-105.27,40.03,-105.25 附近的骑行路段,这些路段的 Cat 等级为 4 或更高。”
- LLM 操作: 调用
explore-segments
,其中bounds: "40.01,-105.27,40.03,-105.25"
,activityType: "riding"
,maxCat: 4
。
- LLM 操作: 调用
- 用户: “将路线 12345 保存为 GPX 文件。”
- LLM 操作: 调用
export-route-gpx
,其中routeId: 12345
。(需要配置ROUTE_EXPORT_PATH
)。
- LLM 操作: 调用
API 参考
服务器公开以下 MCP 工具:
get-recent-activities
获取经过身份验证的用户的最近活动。
- 何时使用: 当用户询问他们最近的锻炼、活动、跑步、骑行等时。
- 参数:
perPage
(可选):- 类型:
number
- 描述:要检索的活动数。
- 默认值:30
- 类型:
- 输出: 最近活动的格式化文本列表(名称、ID、距离、日期)。
- 错误: 缺少/无效的令牌、Strava API 错误。
get-athlete-profile
获取经过身份验证的运动员的个人资料信息。
- 何时使用: 当用户询问他们的个人资料详细信息、用户名、位置、体重、高级状态等时。
- 参数: 无
- 输出: 包含个人资料详细信息的格式化文本字符串。
- 错误: 缺少/无效的令牌、Strava API 错误。
get-athlete-stats
获取经过身份验证的运动员的活动统计数据(最近、YTD、所有时间)。
- 何时使用: 当用户询问他们的总体统计数据、跑步/骑行/游泳的总数、个人记录(最长骑行、最大爬坡)时。
- 参数: 无
- 输出: 统计数据的格式化文本摘要,尊重用户的测量偏好。
- 错误: 缺少/无效的令牌、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、时间、距离、心率、功率、排名等)的格式化文本字符串。
- 错误: 缺少/无效的令牌、无效的
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 错误。
贡献
欢迎贡献!请随时提交 Pull Request。
许可证
本项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 LICENSE 文件。(假设为 MIT,如果不同则更新)
致谢
- Strava 提供公共 API。
- 模型上下文协议 (MCP) 社区。
令牌处理
此服务器实现自动令牌刷新。当初始访问令牌过期(通常在 6 小时后)时,服务器将自动使用存储在 .env
中的刷新令牌来获取新的访问令牌和刷新令牌。然后,这些新令牌会在运行的进程和 .env
文件中更新,从而确保持续运行。
您只需要运行 scripts/setup-auth.ts
脚本一次即可进行初始设置。
身份验证脚本演练
setup-auth.ts
脚本可以轻松设置与 Strava API 的身份验证。这是一个详细的演练,其中包含屏幕截图和说明:
1. 创建 Strava API 应用程序
在运行脚本之前,请转到 https://www.strava.com/settings/api 并创建一个新应用程序:
- 输入您的应用程序详细信息(名称、网站、描述)
- 重要提示:将“授权回调域”设置为
localhost
- 记下您的客户端 ID 和客户端密钥
2. 运行设置脚本
# 在您的 strava-mcp 目录中
npx ts-node scripts/setup-auth.ts
您将看到一条欢迎消息:
--- Strava API 令牌设置 ---
3. 输入客户端凭据
如果您的 .env
文件尚未包含您的 Strava API 凭据,系统将提示您输入它们:
输入您的 Strava 应用程序客户端 ID:[your_client_id]
输入您的 Strava 应用程序客户端密钥:[your_client_secret]
4. 浏览器授权
该脚本将生成一个授权 URL:
步骤 1:授权应用程序
请在您的浏览器中访问以下 URL:
https://www.strava.com/oauth/authorize?client_id=12345&response_type=code&redirect_uri=http://localhost&approval_prompt=force&scope=profile:read_all,activity:read_all
授权后,Strava 会将您重定向到 http://localhost。
从浏览器地址栏中的 URL 复制“code”值。
(例如,http://localhost/?state=&code=THIS_PART&scope=...)
- 在您的浏览器中打开此 URL
- 如果需要,登录 Strava
- 在权限屏幕上单击“授权”
- 您将被重定向到
localhost
(这将显示连接错误 - 这是正常的) - 查看浏览器的地址栏以查找授权代码:
代码是http://localhost/?state=&code=1a2b3c4d5e6f7g8h9i0j&scope=read,activity:read_all,profile:read_all
code=
之后和&scope=
之前的部分
5. 完成 OAuth 流程
- 从浏览器复制授权代码
- 返回到您的终端并在提示时粘贴代码:
在此处粘贴授权代码:1a2b3c4d5e6f7g8h9i0j
- 该脚本会将此代码交换为访问令牌和刷新令牌
6. 将令牌保存到 .env
当要求将令牌保存到您的 .env 文件时,输入“yes”:
您要将这些令牌保存到您的 .env 文件吗? (yes/no): yes
✅ 令牌已成功保存到 .env 文件。
您的 .env
文件现在将包含所有必需的凭据:
STRAVA_CLIENT_ID=your_client_id
STRAVA_CLIENT_SECRET=your_client_secret
STRAVA_ACCESS_TOKEN=your_generated_access_token
STRAVA_REFRESH_TOKEN=your_generated_refresh_token
7. 构建并启动服务器
现在已设置身份验证,请构建并启动服务器:
npm run build
npm start
您应该看到:
正在启动 Strava MCP 服务器...
Strava MCP 服务器已通过 Stdio 连接。工具已注册。
完成这些步骤后,您的 MCP 服务器已准备好向兼容的 LLM 客户端提供 Strava 数据,并具有自动令牌刷新处理功能。
推荐服务器
Crypto Price & Market Analysis MCP Server
一个模型上下文协议 (MCP) 服务器,它使用 CoinCap API 提供全面的加密货币分析。该服务器通过一个易于使用的界面提供实时价格数据、市场分析和历史趋势。 (Alternative, slightly more formal and technical translation): 一个模型上下文协议 (MCP) 服务器,利用 CoinCap API 提供全面的加密货币分析服务。该服务器通过用户友好的界面,提供实时价格数据、市场分析以及历史趋势数据。
MCP PubMed Search
用于搜索 PubMed 的服务器(PubMed 是一个免费的在线数据库,用户可以在其中搜索生物医学和生命科学文献)。 我是在 MCP 发布当天创建的,但当时正在度假。 我看到有人在您的数据库中发布了类似的服务器,但还是决定发布我的服务器。
mixpanel
连接到您的 Mixpanel 数据。 从 Mixpanel 分析查询事件、留存和漏斗数据。

Sequential Thinking MCP Server
这个服务器通过将复杂问题分解为顺序步骤来促进结构化的问题解决,支持修订,并通过完整的 MCP 集成来实现多条解决方案路径。

Nefino MCP Server
为大型语言模型提供访问德国可再生能源项目新闻和信息的能力,允许按地点、主题(太阳能、风能、氢能)和日期范围进行筛选。
Vectorize
将 MCP 服务器向量化以实现高级检索、私有深度研究、Anything-to-Markdown 文件提取和文本分块。
Mathematica Documentation MCP server
一个服务器,通过 FastMCP 提供对 Mathematica 文档的访问,使用户能够从 Wolfram Mathematica 检索函数文档和列出软件包符号。
kb-mcp-server
一个 MCP 服务器,旨在实现便携性、本地化、简易性和便利性,以支持对 txtai “all in one” 嵌入数据库进行基于语义/图的检索。任何 tar.gz 格式的 txtai 嵌入数据库都可以被加载。
Research MCP Server
这个服务器用作 MCP 服务器,与 Notion 交互以检索和创建调查数据,并与 Claude Desktop Client 集成以进行和审查调查。

Cryo MCP Server
一个API服务器,实现了模型补全协议(MCP),用于Cryo区块链数据提取,允许用户通过任何兼容MCP的客户端查询以太坊区块链数据。