Skip to main content
Glama
henryhf
by henryhf

FitCoach MCP

一个远程 MCP 服务器,能把 Claude 或 ChatGPT 变成一位有记忆的健身教练:目标可持久化、训练记录通过对话完成、按用户进行参数拟合,以及一个每周一次的“plan my sessions”仪式,生成一份带版本且附有说明的训练计划。

分工方式: LLM 负责捕捉对话并进行叙述;src/engine/ 中的确定性引擎负责一切编程式决策(渐进超负荷、训练量、减载、动作替换、跑步配速、自动调节)。同样的输入,永远得到同样的计划。

事实只存放于一个地方

docs/CURRENT-STATE.md 是唯一事实来源,涵盖数量、常量、部署身份,以及已实现与未实现的事项。本 README 有意只复述其中尽可能少的内容,因为 2026 年 8 月的一次审计发现,此文件、RUNBOOK 和 SUBMISSION-PACK 都各自声称有 11 个工具,而实际是 22 个。如果这里某个数字与 CURRENT-STATE 不一致,CURRENT-STATE 为准,且本文件已失效。如果 CURRENT-STATE 与代码不一致,请先修复 CURRENT-STATE。

Related MCP server: WorkoutGuide MCP

产品机制

  • 原始日志只能添加。 期次、组数、反馈、跑步和恢复指标可不会被编辑——一切智能内容都是 user_params 中的派生状态(e1RMs、趋势、停滞检测、恢复评分、容量里程碑、跑步表现),并在每次规划时重新调整。

  • 计划有版本。 每次 plan_my_week 都会取代上一版,并记录父指针加上一段人类可读的说明——“git,去掉 git。”git——减去 git。”

  • 试用不是一个周期,而是一 TRIAL_DAYS = 35(一个 28 天的计划周期 + 7 天尊期,由第一次 log_workoutplan_my_weeklog_run 起算。onboarding 和 import_history 有意不启动它。读取型工具永远不被锁定,delete_my_account 永远不受门禁——你的数据永远属于你。

  • 升级发生在对话之中。 被拦截的写工具会把一条热情友好的升级消息作为工具 content(而不是 error)返回,这样模型可以在用户正有意之时把它转达给用户。

  • EARLY_ACCEESS 现在是 ON,所以目前没有任何门禁,试用时钟也永远不会开始。门禁已完整实现并通过测试;只是这个 flag 把它保持打开。见 CURRENT-STATE → Entitlements。

  • 安全安检。 src/server/safety.ts 会对全部 9 个可选用户自由文本输入面运行确定性红线匹配器(都枚举在一处:src/server/tools.ts 中的 freeTextSources())。一旦触发紧急级匹配,就会把响应中其他一切全部去除,包括升级页脚——而且它也会运行在 entitlements 拦截路径上,因此一个同样被拦截的用户报告到胸到胸痛,也会得到的就是升级提示,而不是销售话术。

快速开始(本地)

npm install
npm test                       # full suite; see CURRENT-STATE for the current count
AUTH_MODE=dev npm run dev      # Streamable HTTP MCP server on :3000

AUTH_MODE必须且必须显式——如果它未设置或不是 dev / supabase 之外的值,服务器就会拒绝启动:

Fatal startup error: Error: Unknown or missing AUTH_MODE null. Set AUTH_MODE=dev or AUTH_MODE=supabase

本仓库任何地方都不会加载 .env 文件——没有 dotenv 依赖,也没有 dev 脚本上的 --env-file 标志。.env.example 只是相关的变量文档,但把它复制为 .env 不产生且有效:要么像上面那样内联传递变量,要么通过 export 把它导出,要么自己加 --env-file=.env

运行后有两个探针,二者含义不同: curl localhost:300/healthz 会不触碰数据库就返回 {"ok":true}(存活检查——Fly 每 30 秒轮询它,所以数据库瞬时抖动不能让它失败);curl localhost:300/readyz 会真正查一次数据库并返回 {"ok":true,"db":"up","durationMs":N}(或返回 503 db:down)。外部监控真正关注的只有一个,那就是 /readyz

dev 模式下,任何 dev-<name> 的承载 token 都会以用户 <name> 的身份完成验证;当 NODE_ENV=production 时它会被直接拒绝。

从 Claude(自定义连接器)或 MCP Inspector 连接,URL 使用 http://localhost:3000/mcp,Header 加上 Authorization: Bearer dev-henry,然后可以试试:设置 profile、设一个 goal、记录一个 workout、以及 plan my week

npm 中其它关键词:npm run build(运行tsc 并把 migrations 复制到 dist/)、npm start(运行构建产物)、npm run test:watchnpm run provision(Supabase)、npm run seed-demonpm run metricsnpm run deploy`(见 部署)。

存储配置

一个函数决定后端: src/storage/select.ts 中的 createStorage(),在 src/server/index.ts 中调用。

DATABASE_URL

后端库

用途

条件设置

PostgresStorage——Supabase Postgres,推荐事务连接池 URL(端口 543)

生产条件

未设置,dev/test

PgliteStorage——嵌入的 Postgres,可用 DATA_DIR 可选持久化

开发与测试

未设置,production 类型

启动时即抛异常

“production 类型” 指 “production 环境” = NODE_ENV=production AUTH_MODE=supabase,而且该拒绝行为是有意为之。DATA_DIRfly.toml 中故意未设置,因此旧的 PGlite 回退实际是 in-memory:服务器能干净启动,/healthz 仍是 green,工具调用成功,而每次重启都会让用户得到一个全新的空账户。也就是说,一个落掉的 secret 看起来几乎就像一个毫无问题的部署。现在它能响而且会响(见 tests/storage-select.test.ts)。

二者都是对同一 Storage 接口的完整实现,并运行同一套迁移(src/storage/migrations/0001_init0015_rls_v7,配套的 _rls_ 文件中包含 RLS 规则)。PGlite 不是 一个 stub,Postgres 也不是“未来才能用”:PostgresStorage 是完整并已交付的实现,线上部署跑的正是它。两个后端不可漂移的唯——点数据——population tuning 关系——完全共享自 src/storage/tuning-shared.ts

PostgresStorage.init() 在启动时按顺序执行每个迁移。可移植的文件是加性且幂等的,因此对实时库重新运行是安全的;_rls_ 文件引用了 Supabase 内的 auth.uid(),仅当所连接数据库有该函数时才会自动在本库(plain Postgres)和本地 CI 中自动应用,否则跳过。只有 PORT 环境注记……好,准确的自己。

注意,如果没有真实 DB 那么 71 个测试会被跳过。发布前要对着 Postgres 跑一次测试套件,而不是只跑 PGlite。

部署方式

Fly 应用是 fitcoach-hs——不是包的名称。fly.tomlscripts/deploy-fly.sh 都以它命名,因此一个“bare deploy”就可以了:

FLY_API_TOKEN=... npm run deploy

(直到 0.7.1 之前,二者都默认 fitcoach-mcp,所以此前一个裸 deploy 会 创建 那个应用、部署那里并健康测试它的 URL——即对一个没人使用的应用只做了一堆 green 健康运行。如果在 Fly 账户上仍有当时残留的 fitcoach-mcp 应用,请 flyctl apps destroy fitcoach-mcp;一个能响应 /healthz 的假应用比没有应用更糟。)

fly.toml 声明了 [[mounts]] volume,这是有意的——它和当前运行的机器匹配,从而让部署过程不再询问任何 prompt。volume 本身未使用(生产数据在外部 Postgres 上),但它将 app 固定到单独的机器上,这是进程内 rate limiter 所依赖的。详见 docs/DEPLY-NOTES.md

架构

src/
  types.ts            # binding contracts: domain, Storage, Engine, TOOL_NAMES
  storage/
    migrations/       # 0001..0015; portable DDL + paired Supabase RLS policies
    select.ts         # createStorage(): DATABASE_URL ? Postgres : PGlite
    postgres.ts       # production Storage impl (Supabase Postgres)
    pglite.ts         # dev/test Storage impl (embedded Postgres)
    tuning-shared.ts  # the aggregates-only tuning evidence SQL, shared by both
    seed-exercises.ts # exercise catalog: substitutes, movement pattern, fatigue cost
  engine/             # deterministic; see docs/INTELLIGENCE-DESIGN.md
    e1rm.ts           # Epley + RPE→RIR adjustment
    fitting.ts        # fitParams: e1RM smoothing, trends, stalls, freshness, landmarks
    planner.ts        # planWeek: splits, progression, deloads, hybrid day layout
    running.ts        # run fitness, program-mode arbitration, run-week construction
    adjust.ts         # same-day autoregulation (short on time / beat up)
    alignment.ts      # goal-vs-behaviour drift detection, proactive check-ins
    experiments.ts    # 2-week n-of-1 plateau tests
    recap.ts          # weekly recap + PR detection
    tuning.ts         # bounded population tuning from aggregate evidence
  server/
    index.ts          # express + stateless StreamableHTTP, per-request server factory
    auth.ts           # dev tokens / Supabase JWT (JWKS) + RFC 9728 metadata
    consent.ts        # OAuth 2.1 consent UI (Supabase as authorization server)
    entitlements.ts   # mesocycle trial gate + EARLY_ACCESS
    metering.ts       # idempotent usage events
    safety.ts         # deterministic red-flag screen (emergency / injury)
    temporal.ts       # server-side, timezone-aware natural-language dates
    rate-limit.ts     # in-process burst + sustained limits
    tools.ts, tools-*.ts, tools/*.ts   # the tool surface (see CURRENT-STATE)
    pages/, site.ts, share.ts, ui/     # landing, /connect, /docs, share links
  billing/provider.ts # BillingProvider interface + StubBillingProvider

没有接入任何支付服务商。 运行的是 Publishing billing 实例,且 CHECKOUT_BASE_URL 未设置,所以结账链接都回到 /#pricing 区块。Stripe 是 runbook 里的 Phase 7。

文档资料

文档

内容

docs/CURRENT-STATE.md

事实来源——计数、身份标识、已实现/未实现项

docs/INTELLIGENCE-DESIGN.md

训练引擎的原理:每一个算法、常量、护栏

docs/RUNBOOK.md-

操作手册——环境变量、部署、EARLY_ACCE、速率限制、认证

docs/INCINDENT-RUNBOOK.md

它挂掉了(或看似挂掉):T前调探针和根因手册

docs/PRIVACY-CHECKLIST.md

本产品存储injury notes、wellbeing 文本——请按敏感信息处理

docs/DEPLY-NOTES.md

Fly 特有事项

docs/WEARABLES.md

可穿戴设备指标单读入

docs/SUBMISSION-PACK.md

计划提交所需材料

F
license - not found
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes Whoop fitness data (recovery, sleep, strain, workouts) to Claude for use as a daily training coach, enabling natural language queries about your health metrics and training readiness.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables workout tracking and coaching within Claude conversations, managing exercise configs, logs, streaks, and health metrics via an MCP server with PostgreSQL.
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables Claude to analyze training data from spreadsheets and Amazfit watches, providing insights on strength progression, running metrics, recovery status, and readiness, with tools for weekly reviews, exercise progression, and health reporting.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Create Hevy routines and analyze your training from chat. Unofficial; BYO Hevy PRO API key.

  • WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.

  • Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.

View all MCP Connectors

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/henryhf/fitcoach-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server