运动员上下文管理协议

用于持久化铁人三项运动员在Claude对话中的生理数据、训练目标和日常状态的服务器协议

  • by kerfich
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 kerfich/athlete-context-mcp

使用说明

运动员背景mcp-v0.3.1

MCP(模型上下文协议)服务器,用于持久化运动员的上下文 对话之间的铁人三项克劳德:生理概况,目标 季节、训练政策、每日状态、笔记日志和 睡眠监测(HRV、债务、流量)。


索梅尔


安装

git clone https://github.com/kerfich/athlete-context-mcp
cd athlete-context-mcp
npm install
npm run build        # compile TypeScript → dist/

先决条件: 节点20+.


配置克劳德桌面

文件: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

推荐配置(本地构建)

{
  "mcpServers": {
    "athlete": {
      "command": "/bin/bash",
      "args": [
        "-lc",
        "exec 2>>\"$HOME/athlete-mcp.log\"; export PATH=/opt/homebrew/opt/node@20/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin; export ATHLETE_MCP_DATA_DIR=\"$HOME/Library/Application Support/athlete-context-mcp\"; /opt/homebrew/opt/node@20/bin/node /CHEMIN/VERS/athlete-context-mcp/dist/index.js"
      ]
    }
  }
}

替换 /CHEMIN/VERS/athlete-context-mcp 通过克隆repo的绝对路径。

修改后重新启动Claude桌面。

使用调试模式

{
  "mcpServers": {
    "athlete_debug": {
      "command": "/bin/bash",
      "args": [
        "-lc",
        "exec 2>>\"$HOME/athlete-mcp-debug.log\"; export PATH=/opt/homebrew/opt/node@20/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin; export MCP_DEBUG=1; export ATHLETE_MCP_DATA_DIR=\"$HOME/Library/Application Support/athlete-context-mcp-debug\"; /opt/homebrew/opt/node@20/bin/node /CHEMIN/VERS/athlete-context-mcp/dist/index.js"
      ]
    }
  }
}

环境变量

变量 默认值(macOS) 描述
ATHLETE_MCP_DATA_DIR ~/Library/Application Support/athlete-context-mcp SQLite数据库目录
MCP_DEBUG — 1 要启用内部日志

可用工具

独自创立

get_context ⭐

呼叫开始对话。返回单个请求: 个人资料+目标+政策+当前状态+3个最新评级+趋势睡眠7天。

{}

个人资料

get_athlete_profile

返回完整配置文件(版本化)。

{}

upsert_athlete_profile

创建或更新配置文件。所有字段都是可选的;只有他们 发送的字段被持久化(与ZOD条带合并)。

第一级字段:

冠军 类型 描述
name 字符串 名字/姓氏
age 整数 年龄
weight_kg 数量 重量(kg)
hr_max 整数 FC最大值(bpm)
lthr_run integer LTHR课程(bpm)
ftp_bike_ref 整数 FTP自行车参考(W)
ftp_bike_current 整数 FTP当前自行车(W)
hr_zones_run HRZone[] 7区FC课程
hr_zones_bike HRZone[] FC韦洛7区
pace_zones_run PaceZone[] 5个区域吸引球场
biomechanics_targets 目标 生物力学目标(Cadence、GCT、OV、VR)
injury_history 伤害[] 病史
training_pattern 对象 正常训练日
equipment 对象 可用材料
schedule_constraints 对象 承包商计划
session_naming_convention 对象 会话命名规则
training_volume_targets 目标音量和频率
constraints 字符串[] 自由约束

equipment :

bike_name, shoes_run_name, wetsuit (bool), power_meter (bool),
heart_rate_monitor (bool), smart_trainer (bool), swim_goggles (bool), notes

schedule_constraints :

available_days (string[]), unavailable_days (string[]),
preferred_time (morning|midday|evening|flexible),
max_session_duration_min, min_rest_days_per_week, notes

session_naming_convention :

format (e.g. "{date}_{discipline}_{type}_{duration}min"),
prefix, date_format, discipline_codes (record string→string), example, notes

training_volume_targets :

weekly_run_km, weekly_bike_km, weekly_swim_m,
sessions_per_week_run, sessions_per_week_bike, sessions_per_week_swim,
long_run_km, long_bike_km, phase, notes

目标

get_athlete_goals

返回季节目标(版本化)。

upsert_athlete_goals

events: Event[]          — Liste des courses/épreuves
  name, date (YYYY-MM-DD), discipline (run|triathlon|swim|bike|vtt)
  priority (A|B|C), target_time?, notes?
current_phase?:
  code (P0|P1|P2…), description, start_date, current_week,
  target_weekly_volume_km
season_notes?

政策

get_athlete_policies

返回活动训练规则(版本化)。

upsert_athlete_policies

rules: PolicyRule[]
  id, description, condition?, action?,
  severity (info|warn|block)

每日状态

get_athlete_state

返回当前状态:从注释+上次计算的度量 主观评估。

update_athlete_state

记录当天的主观状态并重新计算指标。

ankle_pain      0–10   Douleur cheville
fatigue         0–10   Fatigue subjective
sleep_quality   0–10   Qualité sommeil
comment?               Commentaire libre

计算指标(注释的最后14天):

  • stress_trend_7d, rpe_trend_7d
  • pain_watchlist :前3个疼痛区域(发生率+平均强度)
  • solo_ratio_14d
  • readiness_subjective 0–100 : 100 - 5×stress - 3×rpe - 8×pain_max
  • flags : high_stress, pain_risk

备注

add_note

添加注释(会话分析、每周报告、决策规划)。

note_text*    string   Contenu complet (requis, minLength: 1)
note_date?    string   YYYY-MM-DD (défaut: aujourd'hui)
type?         enum     analyse_seance | bilan_semaine | decision_plan
                       | state_update | general
tags?         string[] Ex: ["run", "vélo", "récupération"]
activity_id?  string   ID activité Garmin (optionnel)

返回 note_id (完整)用于后续恢复。

自动提取分析 note_text 要提取: RPE、压力、睡眠、社会背景、疼痛区域。

get_note

通过其数字标识符检索注释。

note_id   integer   ID retourné par add_note

search_notes

使用可组合过滤器搜索注释。

query?      string   Recherche plein texte
date_from?  string   YYYY-MM-DD
date_to?    string   YYYY-MM-DD
type?       enum     (voir add_note)
tags?       string[] Filtre par tags (matching OR)
limit?      integer  Défaut 10

睡眠

upsert_sleep_log

插入或更新给定夜晚的睡眠输入。重新发送 相同 date 覆盖上一个输入(Garmin同步后理想)。 孤独 date 是强制性的。

date*           string   YYYY-MM-DD (requis)
duration_min?   integer  Durée effective en minutes
score?          integer  Score Garmin 0–100
qualifier?      enum     poor | fair | good | excellent
hrv_avg_ms?     number   HRV nocturne moyenne (RMSSD, ms)
hrv_status?     enum     balanced | unbalanced | low
hrv_baseline_low/high?  number  Fourchette baseline personnelle (ms)
resting_hr_bpm? integer  FC repos (bpm)
deep_pct?       number   % sommeil profond
rem_pct?        number   % sommeil REM
light_pct?      number   % sommeil léger
awake_min?      integer  Minutes d'éveil nocturne

get_sleep_trends

返回过去n晚计算的总输入+度量 (默认值14,最大值30)。

days?   integer   Fenêtre d'analyse en nuits (défaut 14, max 30)

返回的度量 trends :

度量 描述
unbalanced_streak 连续住宿(自最近起) hrv_status ≠ balanced
sleep_debt_7d_min 过去7晚(分钟)的累积赤字与目标7小时/晚
avg_duration_7d_min 平均7晚
avg_score_7d 7晚平均Garmin评分
hrv_avg_7d 7晚平均HRV
hrv_trend improving / stable / declining / insufficient_data (最近3晚与前3晚的比较,阈值±3 ms)
qualifier_dist_7d 分布 { poor, fair, good, excellent } 7晚

数据模式

HRZone

zone (1–7), name?, min_bpm?, max_bpm?

PaceZone

zone (1–5), name?, min_pace_per_km? ("mm:ss"), max_pace_per_km?

受伤

area, description?, start_date?, end_date?, severity (0–10)?

自动提取(note-text)

冠军extrait 图案重新连接
rpe 1–10 RPE 7, 8/10, ressenti=6
stress 0–10 stress 6/10, stress=4
sleep_quality 0–10 sommeil 7/10, sleep=8
social_context seul/solo → solo, couple → 情侣, amis → amis, club → 俱乐部
pain[].area 小腿、膝盖、胫骨、肌腱、臀部、背部、脚踝、肩膀
pain[].intensity 数字 /10 或 = N 在区域名称之后

SQLite数据库

默认路径(macOS): ~/Library/Application Support/athlete-context-mcp/athlete.db

启动时自动创建和迁移。

CREATE TABLE IF NOT EXISTS versions_profile
  (id INTEGER PRIMARY KEY, version INTEGER, json TEXT, updated_at TEXT);

CREATE TABLE IF NOT EXISTS versions_goals
  (id INTEGER PRIMARY KEY, version INTEGER, json TEXT, updated_at TEXT);

CREATE TABLE IF NOT EXISTS versions_policies
  (id INTEGER PRIMARY KEY, version INTEGER, json TEXT, updated_at TEXT);

CREATE TABLE IF NOT EXISTS versions_state
  (id INTEGER PRIMARY KEY, version INTEGER, json TEXT, updated_at TEXT);

CREATE TABLE IF NOT EXISTS notes (
  id            INTEGER PRIMARY KEY AUTOINCREMENT,
  activity_id   TEXT,
  note_date     TEXT,
  type          TEXT,        -- migration automatique sur ancienne DB
  raw_text      TEXT,
  tags_json     TEXT,
  extracted_json TEXT,
  created_at    TEXT
);

CREATE TABLE IF NOT EXISTS sleep_log (
  id                INTEGER PRIMARY KEY AUTOINCREMENT,
  date              TEXT UNIQUE NOT NULL,   -- clé d'upsert
  duration_min      INTEGER,
  score             INTEGER,
  hrv_avg_ms        REAL,
  hrv_status        TEXT,
  hrv_baseline_low  REAL,
  hrv_baseline_high REAL,
  resting_hr_bpm    INTEGER,
  deep_pct          REAL,
  rem_pct           REAL,
  light_pct         REAL,
  awake_min         INTEGER,
  qualifier         TEXT,
  created_at        TEXT,
  updated_at        TEXT
);

桌子 versions_* 存储单个记录 id=1 具有:

  • version :每次递增 upsert
  • json :序列化数据
  • updated_at :ISO 8601

Robustesse SQLite(多实例)

  • 瓦尔(journal_mode = WAL)用于竞争阅读
  • busy_timeout = 5000ms
  • 指数重试 SQLITE_BUSY/SQLITE_LOCKED :5个试探,后退50个→100→200→300→500 ms

调试

# Logs dans ~/athlete-mcp.log
tail -f ~/athlete-mcp.log

# Mode debug (logs SQLite + répertoire de données)
MCP_DEBUG=1 node dist/index.js

# Test d'initialisation
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' \
  | node dist/index.js

# Liste des tools
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | node dist/index.js | python3 -m json.tool

建筑

文件 角色
src/index.ts 注册14个MCP工具,传输stdio
src/models.ts ZOD模式(个人资料、目标、政策、笔记、状态、睡眠)
src/tools.ts CRUD(SQLite)实现,计算睡眠趋势
src/state.ts 计算从注释导出的度量
src/extractor.ts 从中提取启发式 note_text
src/db.ts 初始化SQLite,迁移,重试

笔记技巧 — inputSchema :过去的ZOD方案 server.tool() 使用 .shape (物镜 { clé: ZodType })没有实例 ZodObject 直接。 MCP SDK v1.25+检测ZodObject实例并将其视为 annotations, 离开 inputSchema 空-这将导致所有调用失败。


更新日志

v0.3.1

  • Nouveau工具 : upsert_sleep_log -每晚输入(日期、持续时间、分数、HRV、FC休息、阶段、资格赛),语义为 date
  • Nouveau工具 : get_sleep_trends -N晚计算的趋势: unbalanced_streak, sleep_debt_7d_min, hrv_trend (改善/稳定/下降), qualifier_dist_7d,平均分数/持续时间/HRV
  • get_context :现在包括 sleep: get_sleep_trends(7) pour le bootstrap
  • 表SQLite sleep_log 启动时自动创建(安全迁移)

v0.3.0

  • 修复批评 : inputSchema 正确暴露(.shape au lieu de ZodObject)
    →参数现在被接收并保留在处理程序中
  • Nouveau工具 : get_context -一次呼叫中的引导(配置文件+目标+政策+状态+3个注释)
  • add_note :冠军 type (枚举), activity_id 可选,防护 note_text
  • update_athlete_state :é主观评价(踝关节疼痛、疲劳、睡眠质量、评论)
  • search_notes :过滤date_from/date_to、类型、标签
  • upsert_athlete_profile :4个新字段- equipment, schedule_constraints, session_naming_convention, training_volume_targets
  • 自动数据库迁移:列 type 在桌子上 notes
  • 防御卫队 add_note 和 extractFromText

v0.2.2

  • 数据目录可通过以下方式配置 ATHLETE_MCP_DATA_DIR
  • 支持macOS ~/Library/Application Support

v0.2.0版本

  • STDIO传输,官方MCP SDK
  • 工具:获取/升级配置文件、目标、策略、注释、状态