mcpField
O
ourpr-mcp-server

ourpr-mcp-server

本地服务
github.com/joeyaflores健康医疗04 周前更新

关于 ourpr-mcp-server

ourpr-mcp-server 是面向跑者的 MCP 服务,可让 AI Agent 查询个人 ourpr 训练记录,并在获得写入授权后为未来日期添加计划。工具将简要记录查询与详细活动数据分开,且仅允许写入训练计划。

主要功能

  1. 01按日期范围查询跑步记录
  2. 02查看活动详情、轨迹数据和分段
  3. 03查找间歇训练、比赛和相似地形
  4. 04查看当前及过往训练周期
  5. 05列出已有计划并安排未来跑步

适用场景

  1. 01汇总跑量或查找长距离跑步
  2. 02查看分段数据和间歇训练
  3. 03比较比赛前的训练周期
  4. 04添加下周的跑步计划

MCP 相关

向 MCP 客户端提供 ourpr 跑步记录和计划工具。大多数工具仅用于读取;唯一写入工具 `ourpr_plan_week` 需要带 Write 权限的令牌和 ourpr create 账户。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"joeyaflores-ourpr": {
"command": "npx",
"args": [
"-y",
"ourpr-mcp-server"
],
"env": {
"OURPR_TOKEN": "<OURPR_TOKEN>"
}
}
}
}
启动命令npx -y ourpr-mcp-server
需要配置的环境变量
OURPR_TOKEN密钥Your personal access token from ourpr Settings.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmourpr-mcp-server0.5.0

工具

11

收录的工具列表 · 更新于 2 周前

参数类型必填说明
limitinteger否最多返回的行数。未包含的内容会在答复中说明。
end_datestring是要包含的最后一天,格式为 YYYY-MM-DD。示例:2026-06-30
start_datestring是要包含的第一天,格式为 YYYY-MM-DD。示例:2026-01-01
include_non_runsboolean否包含骑行、健身房训练和其他类型。默认仅包含跑步。

详细介绍

ourpr-mcp-server

一个 MCP 服务,可让 AI Agent 读取你在 ourpr 上自己的跑步记录,并写入一项内容。用日常语言询问你的训练情况,可使用你现有的任意 Agent。

每个工具都可读取。只有一个工具可以写入,而且仅限这一个:ourpr_plan_week 会将计划安排在未来的某一天。它无法记录跑步、编辑历史记录或签发其他凭据,并且需要使用带有写入权限范围的令牌。

在 Claude 中,你不需要这个软件包。添加 ourpr.,网址为 https://ourpr.app/your-runs:它只需让你登录一次,无需令牌,也无需安装任何内容。这个软件包适用于脚本或你自己电脑上的 Agent。

价格

读取你自己的跑步记录是免费的。计划功能属于 ourpr create,每月 $10,可随时取消:只有订阅了该服务的账户才能使用 ourpr_plan_week。ourpr 的其他功能均不收费。

存在的意义

在 ourpr 中,每次经过身份验证的读取都需要一个有效期约一小时的会话,因此浏览器之外的任何程序都无法持有该会话。个人访问令牌改变了这一点,这正是令牌的用途:在你的工具中访问你的数据,并使用由你自己签发且可撤销的凭据。

设置

1. 创建令牌。 在 ourpr 中,前往 Settings → ourpr. mcp → Tokens for a script or a local server → New token。用令牌所在的机器为它命名;如果你希望 Agent 为你规划本周安排,请选择 Write,否则选择 Read。复制令牌——它只会显示一次,之后无法找回。令牌有效期为 90 天。

2. 将客户端指向令牌。 此软件包通过 npm 运行,无需克隆。

不要将令牌放进项目中的任何文件。 项目的 .mcp.json、.cursor/mcp.json 或 .vscode/mcp.json 通常会提交到代码库,而任何能读取代码库的人都能读取已提交的令牌。以下所有设置都会将令牌保存在用户级位置或系统的机密存储区中。

固定版本。 每种设置都会指定一个精确版本,因此除非你主动选择更新,否则新版本不会使用你的令牌运行。修改版本号即可更新。

Claude Code

在不回显令牌的情况下读取它,避免令牌进入 shell 历史记录,然后将服务添加到你的用户配置中,而不是项目配置中:

printf 'Token: '; read -rs OURPR_TOKEN; echo
claude mcp add --scope user --env OURPR_TOKEN="$OURPR_TOKEN" --transport stdio \
  ourpr -- npx -y [email protected]
unset OURPR_TOKEN

Claude Code 会将其保存在属于你用户的 ~/.claude.json 中。

Claude Desktop

从最新版本中下载 ourpr.mcpb 并打开。Claude Desktop 会询问令牌,并将其保存在系统的机密存储区中。推荐使用这种方式。

或者编辑位于用户文件夹(而非项目中)的 claude_desktop_config.json。这样令牌会以纯文本形式保存在该文件中:

{
  "mcpServers": {
    "ourpr": {
      "command": "npx",
      "args": ["-y", "[email protected]"],
      "env": { "OURPR_TOKEN": "ourpr_pat_..." }
    }
  }
}
VS Code

运行 MCP: Open User Configuration,并在那里添加服务。VS Code 会询问一次令牌,将其隐藏,并保存在机密存储区中:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "ourpr-token",
      "description": "ourpr personal access token",
      "password": true
    }
  ],
  "servers": {
    "ourpr": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "[email protected]"],
      "env": { "OURPR_TOKEN": "${input:ourpr-token}" }
    }
  }
}
Cursor

在 shell 配置文件或系统机密管理器中设置 OURPR_TOKEN,并将服务添加到全局配置文件 ~/.cursor/mcp.json。该文件中只会保存对变量的引用:

{
  "mcpServers": {
    "ourpr": {
      "command": "npx",
      "args": ["-y", "[email protected]"],
      "env": { "OURPR_TOKEN": "${env:OURPR_TOKEN}" }
    }
  }
}
如果令牌泄露

在 Profile → Settings → ourpr. mcp 中撤销令牌,然后创建一个新令牌。撤销会立即生效。

从源代码运行
git clone https://github.com/joeyaflores/ourpr-mcp-server.git
cd ourpr-mcp-server
npm install && npm run build && npm test

协议

此服务使用 MCP 2026-07-28,也能响应使用较旧 initialize 握手的客户端。它基于官方 TypeScript SDK v2(@modelcontextprotocol/server)构建,测试会运行每个版本。

环境变量

OURPR_TOKEN必需。 你的个人访问令牌。
OURPR_API_URL可选。默认为 https://ourpr.onrender.com/api。

令牌是环境变量,而不是工具参数,这是有意为之:它在不同调用之间不会变化,因此若每次调用都传入它,就会将有效凭据放进 Agent 的上下文、对话记录以及任何相关日志中。

工具

每个工具都会读取你导入 ourpr 的内容,以及你在那里记录或计划的内容。 通过 Strava 同步进入 ourpr 的跑步记录不在其中:Strava 的 API Policy(2026)禁止将其 API 数据用于 MCP 服务和 AI 工具。你的 Strava 批量导出数据可供你在任何地方使用,因此导入后,所有跑步记录都会在这里。

ourpr_list_runs

两个日期之间的历史记录,以紧凑表格呈现:日期、名称、类型、英里数、 配速、移动时间、海拔、平均心率。

几乎所有事情都可以从这里开始——统计总量、连续记录、趋势、查找跑步记录。

"How many miles did I run in July?"
"What was my longest run this spring?"
"Show me every run over 15 miles in 2026"

start_date、end_date(YYYY-MM-DD)、include_non_runs、limit。

它绝不会静默截断:如果日期范围内的记录超过 limit,答案会说明有多少条被省略。

ourpr_get_run

一项完整的活动记录,包含每英里分段、心率、步频、卡路里和 记录设备。

"Break down my Boston Marathon splits"
"Did I positive or negative split that half?"
ourpr_run_stream

将一次跑步重采样到固定的 10 米网格——海拔、经过时间,以及手表记录这些数据的位置、 心率、功率和步频。返回每个通道的统计摘要,而不是每个采样点。

返回 404 是正常的:室内跑步没有轨迹剖面。

ourpr_run_laps

手表本身记录的圈数——即跑者自己按下按钮记录的圈数,也就是 田径训练实际划分的依据。它们不同于每英里分段:圈数按照训练安排划分,分段则按照英里划分。

ourpr_rep_workouts

ourpr 能在你的历史记录中找到的所有间歇训练,包含重复组及其 距离。若结果为空,答案会说明读取了多少项活动,因为“未找到”和“不存在”是不同的说法。

ourpr_detect_reps

询问某一次特定跑步是否属于间歇训练。

ourpr_similar_terrain

匹配指定距离和爬升的跑步记录——帮你找到过去完成过的、与正在备战的比赛相似的跑步。

"What have I run that's like Boston — 26 miles, 800 feet of climb?"
ourpr_training_blocks

你的目标比赛及其训练周期:比赛日、距离、目标时间、当前所在的训练周期周数, 以及截至目前每周的英里数。尚未开始的一周会显示无英里数,而不是零。还会列出你过去比赛之前的训练周期, 以及每个周期的成绩、周数和高峰周。

"What week of my Dallas block am I in, and how is my mileage building?"
"How does this block compare with the one before my last marathon?"

past:过去的训练周期数量,按时间从新到旧排列。默认显示三个。

ourpr_list_races

ourpr 在你的历史记录中找到的所有比赛,包括调整赛,通过与应用训练周期相同的检测器查找。每一行都包含 ourpr_get_run 所需的跑步 ID。答案还会列出 5K、10K、半程马拉松和马拉松的最快成绩。

"What is my half marathon PR?"
"List every marathon I have run, with the times"

distance、limit。

ourpr_list_plans

你在两个日期之间(默认从今天起两周内)的每周计划:日期、名称、英里数或时长、标签、备注、 是否有你记录的跑步完成了该计划,以及是否由 ourpr create 创建。Agent 在调用 ourpr_plan_week 之前会先读取此项,因此新计划不会安排到已有计划的日期。

"What do I have planned for the next two weeks?"
"Did I do the runs I planned last week?"

start_date、end_date(YYYY-MM-DD)。

ourpr_plan_week

唯一的写入操作。将一项计划跑步或一周的计划跑步添加到未来的日期。 每项计划都会显示在跑者的每周计划中,跑者可以查看、编辑和删除;当天的计划表会注明该计划来自 ourpr create。它绝不会记录跑步。

"Put a 6 mile easy run on Tuesday and 14 long on Saturday"
"Write me next week: three easy days, one workout, one long run"

plans,一到十四项,每项包含 date(YYYY-MM-DD,晚于今天),以及 miles、minutes、name、note、tag(easy、workout、race)、is_long 中的任意字段。

需要使用 Write 权限范围创建的令牌,以及账户中启用的 ourpr create。 Read 令牌或未启用 create 的账户会在写入任何内容前被拒绝。跑者每天最多可写入 120 项计划。

工具集的选择方式

依据评估,而不是罗列 API。

首先编写了十个答案经过验证的问题,并由一个与此服务不共享任何代码的预言机直接从数据库计算答案 (backend/scripts/mcp_eval_oracle.py)。这些问题揭示了真正重要的因素:十个问题中有九个需要活动时间窗口,三个需要完整查看一次跑步记录,两个需要第二个数据源。

因此,活动时间窗口是必须做得出色的工具——而一个在猜测时看似显而易见的 training_summary 工具,结果却无法回答任何问题,所以没有构建。

其中两个问题通过此服务,按照协议,调用四次工具就能得到答案,而且两者都与预言机的答案完全一致:

Q1 peak week   : 63.6   oracle 63.6   MATCH
Q2 fastest 10mi: 6:23   oracle 6:23   MATCH

上下文才是真正的限制

一个活动时间窗口可以包含 800 次跑步记录。把 800 个完整的活动对象交给 Agent,会摧毁它进行思考所需的上下文,因此 ourpr_list_runs 会返回一张简洁的 markdown 表格,而完整查看一次跑步记录则由单独的工具负责。

数据流也是如此:一次十英里的跑步,每个通道约有 1,600 个样本,五个通道合计就是如此,因此工具返回最小值、平均值、最大值和覆盖率,而不是 8,000 个 Agent 反正也会自行汇总的数字。

安全性

此令牌授予对你自己的跑步记录、目标赛事和计划的读取权限。在 ourpr 中,根据设计,令牌发出的每个查询都仅限于其所有者;并且有一项测试会拒绝可能越权访问的令牌路由。使用写入权限范围创建、并带有 ourpr create 的令牌,也可以通过一条路由将计划写入你自己的周计划,仅此而已。任何令牌都不能记录跑步、签发其他令牌、撤销你现有的令牌,或扩大自身权限范围。

每个令牌每分钟可读取 60 次,每位跑者每天可写入 120 个计划。超过任一限制后,ourpr 会返回 429,并附带 RateLimit 和 Retry-After 标头;工具会告知需要等待多久。

你可以随时在 Profile → Settings → ourpr. mcp 中撤销任何令牌。 撤销会立即生效且永久有效——已撤销的令牌永远无法恢复。

工具结果是不可信内容

跑步记录的名称和描述是用户输入的自由文本,或是从导入数据中获取的内容。它们会与 Agent 的指令进入同一个令牌流,而模型无法区分二者。

两种防护措施,各司其职:

对结构进行净化。 移除控制字符、换行符、零宽字符和双向文本标记;对 | 进行转义,以确保其所在的表格列保持完整;并限制每个字段的长度。否则,名称中的换行符会提前结束表格行,并导致其后的所有列错位——Agent 随后读到的就会是错误答案,而不是拒绝回答。

明确标示边界。 跑者编写的数据会放在 <ourpr-data> 分隔符内返回,并附上一行说明这些是数据,而不是指令。这样能减少提示注入得逞的情况,但无法阻止注入,我们也绝不会把它说成可以阻止。分隔符只包裹文本内容;结构化结果中的字段同样经过净化,只是不带分隔符。

我们刻意没有做的是,针对“忽略之前的指令”及类似说法进行模式匹配。这样做只能疲于应对以不同方式写出这句话的人,而且还会让人误以为内容已变得安全。

绝不打印任何已配置的值

OURPR_TOKEN 不会出现在任何日志、错误消息或工具结果中。

OURPR_API_URL 在进入错误消息之前,会被处理为仅保留协议和主机。它是一个 URL,因此可以包含 user:password@——使用基本身份验证、可自托管的实例很可能会这样做——而错误消息会直接进入 Agent 的对话记录。

这并非假设情况。Node 自带的 fetch 对此类 URL 会产生如下错误:

Request cannot be constructed from a URL that includes credentials:
https://admin:[email protected]:59999/api

消息中包含密码。此服务只有在底层错误消息不包含 @、未配置基础 URL 且不包含令牌时,才会透传该消息;否则会退回到错误代码。

其他属性

不透传令牌。 服务使用环境中的凭据,不会接受 MCP 客户端提供的凭据,这是规范所禁止的。

拒绝重定向。 携带凭据的请求不会跟随重定向。

每次调用都会记录到 stderr — 记录结果、不含查询参数的路径和耗时。日志中绝不会出现令牌。

无状态。 不会创建任何句柄,因此无从劫持。

发布

标记 v* 会通过可信发布(GitHub OIDC,并附带来源证明)发布到 npm;仓库中不会存放令牌。npm run build 会写入捆绑包的入口点;npx @anthropic-ai/mcpb pack 会为发布构建 ourpr.mcpb。server.json 会通过 mcp-publisher publish 在 MCP Registry 中注册该软件包。

可信发布是唯一的发布途径。该软件包的 npm 设置要求启用双重身份验证并禁止使用令牌,因此即使 npm 令牌被盗,也无法发布版本;OIDC 工作流仍可发布。软件包中包含 npm-shrinkwrap.json,因此每次安装解析出的依赖树都与该版本测试过的依赖树相同。每次更改依赖后,都要运行 npm install 并提交 shrinkwrap 文件。

发布时需要在五处更改版本:package.json、npm-shrinkwrap.json(通过 npm install)、manifest.json、server.json,以及 src/index.ts 中的 McpServer。本 README 中的每条安装命令都会固定版本,ourpr 的 lib/agent-connect.ts 中的 AGENT_VERSION 也会固定版本。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。