内容
<p align="center">
<img src="docs/health-mcp-logo.png" alt="health-mcp logo" width="160" />
</p>
# 健康管理个人数据库
> 您的个人健康数据库。您的代理负责输入数据。
一个本地优先的服务器,存储您的营养、生物标志物和可穿戴设备数据。整个系统作为模型上下文协议工具公开,因此任何MCP感知的代理(Hermes、OpenClaw)都可以读写它。网页仪表盘与同一进程一起提供,当您想要查看数据而不是与之交互时。
所有操作都在您的机器上运行。一个SQLite文件。无需账户,无需SaaS,无需遥测。
<p align="center">
<img src="docs/dashboard-today.png" alt="health-mcp dashboard, Today view" width="900" />
</p>
<p align="center">
<sub>捆绑仪表盘的<strong>今日</strong>视图:宏量营养素与目标对比,睡眠/恢复/体重/水分,以及当天的餐食。</sub>
</p>
<p align="center">
<img src="docs/architecture.png" alt="health-mcp architecture: an MCP agent and a browser dashboard both talk to the health-mcp Node process, which stores data in SQLite and syncs Whoop / Oura over OAuth2" width="900" />
</p>
与其构建另一个照片简历卡路里应用程序或自由文本解析器,您可以让代理处理模糊的部分(“我吃了两个鸡蛋和吐司”,“记录这个实验室PDF”,“什么影响我的睡眠评分?”),并让此服务器处理持久的部分:键入模式,原子事务,范围查询,能力门控工具表面,以及一个不会对底层数据撒谎的UI。
---
## 跟踪内容
**营养。** 食物(USDA,开放食品事实,手动输入),由食物/配方/批次/自定义组件组成的餐食,水分,体重,身体测量,宏量营养素目标为 `{min, max}` 界限,以及每日/每周汇总。
**配方和烹饪批次。** 配方按每份宏量营养素缩放。批次是烹饪实例,当您食用时会减少,具有原子减少 `log_meal` 和删除退款。
**记忆餐食。** 给您通常的早餐贴上标签,一次在一个工具调用中重新记录它。保存预解析组件(确定性)或规范自由文本(代理重新估计每次调用)。
**生物标志物和实验室。** 约60种精选生物标志物,植入LOINC代码,默认单位和参考+最佳范围。实验室面板原子插入所有结果。三层范围行走决定每个结果的状态:每个结果的实验室快照→每个生物标志物的默认→精选最佳。常见双单位对(mg/dL ↔ mmol/L,ng/mL ↔ nmol/L等)的单位转换。趋势和“每个标记的最新”查询。
**可穿戴设备。** 目前支持Whoop和Oura通过OAuth2。每个提供商镜像保存原始有效载荷(每行 `raw_json`),以便未来迁移可以将任何字段提升为标准化列而无需重新同步。标准化表(`wearable_sleep`,`wearable_activity`,`wearable_readiness`,`wearable_daily`)让您可以跨供应商读取而无需关心连接哪一个。刷新令牌轮换;并发401不能双倍消费,因为身份验证存储由提供商的互斥锁保护。
**洞察。** `correlate` 在任意两个度量系列上运行Pearson或Spearman,按天/周/月分桶。签名滞后桶将一个系列在时间上移动。向前填充通过间隙携带最后一个值,以便稀疏实验室数据与每日可穿戴分数相关联干净。该工具在目录中隐藏,直到有足够的数据有意义。
---
## 快速开始
### npx
节点 ≥ 20,无需克隆或构建:
```bash
npx health-mcp # http://127.0.0.1:7777, 打开仪表盘
npx health-mcp --stdio # 无头MCP服务器通过stdio
```
状态存储在 `~/.health-mcp/`(一个SQLite文件)。`npx health-mcp --help` 列出每个标志;`npx health-mcp doctor` 运行自检。
### Docker
```bash
git clone https://github.com/lukaisailovic/health-mcp.git
cd health-mcp
cp .env.example .env
# 在.env中放入一个强令牌(需要绑定到环回)
openssl rand -hex 32
docker compose up -d
open http://127.0.0.1:7777
```
数据持久存储在 `health-mcp-data` 命名卷中。如果您希望在磁盘上看到文件,请在 `docker-compose.yml` 中交换卷映射为 `./.health-mcp-data:/data`。
`docker compose down` 停止容器;数据在重启后存活。
您更喜欢预构建的镜像而不是本地构建吗?将 `docker-compose.yml` 指向发布的镜像并删除其 `build:` 块:
```yaml
image: ghcr.io/lukaisailovic/health-mcp:latest # 或固定 :0.1.0 / :0.1
```
每个版本都推送 `:X.Y.Z`、`:X.Y` 和 `:latest`;`:main` 跟踪最新提交。所有镜像都带有构建来源证明。参见 [Releasing](./docs/RELEASING.md).
### 从源码
节点 ≥ 20 和 pnpm。
```bash
git clone https://github.com/lukaisailovic/health-mcp.git
cd health-mcp
pnpm install
pnpm build
pnpm start # http://127.0.0.1:7777, 浏览器自动打开
```
对于带有热重载的开发仪表盘、共享类型和服务器,请在监视模式下运行所有三个:
```bash
pnpm dev
# 服务器在 :7777 上,仪表盘开发在 :5173 上(代理 /api/* 到 :7777)
```
传递 `--no-open` 以保持浏览器关闭,或 `--no-dashboard` 以运行无头MCP/REST服务器。
### 子命令
```bash
pnpm start -- migrate # 应用待处理数据库迁移并退出
pnpm start -- doctor # 自检(数据库pragma,文件模式,令牌熵)
pnpm start -- export /tmp/dump.jsonl # JSONL转储;原始json已编辑除非 --include-raw
pnpm start -- import-usda dump.json # 摄入USDA食品数据中心批量JSON
```
---
## 连接MCP代理
### Hermes / OpenClaw(stdio)
两者都使用标准的MCP配置,因此设置相同: 将health-mcp添加到代理的 `mcpServers`。无需克隆或构建;指向发布的包:
```json
{
"mcpServers": {
"health": {
"command": "npx",
"args": ["-y", "health-mcp", "--stdio"]
}
}
}
```
该块位于代理的MCP设置中;请检查其MCP设置以获取路径。
然后询问您的代理:
- *"记录早餐的鸡蛋和吐司"* → `log_meal`
- *"我的空腹葡萄糖趋势如何?"* → `biomarker_trend`
- *"我的蛋白质摄入量是否与第二天的Whoop恢复相关?"* → `correlate` 搭配 `lag_buckets: 1`
从本地检出运行?使用 `"command": "node"` 搭配 `"args": ["/path/to/health-mcp/apps/server/dist/index.js", "--stdio"]` 在 `pnpm build` 之后,或 `"args": ["--import", "tsx", "/path/to/health-mcp/apps/server/src/index.ts", "--stdio"]` 跳过构建。
### MCP检查
```bash
cd apps/server
pnpm inspect
```
在stdio子进程上打开MCP检查以手动探测工具。
### HTTP / 自定义客户端
Streamable-HTTP传输安装在同一端口的`POST /mcp`上。任何HTTP感知的MCP客户端都指向`http://127.0.0.1:7777/mcp`并在设置令牌时发送`Authorization: Bearer <HEALTH_MCP_TOKEN>`。
第一次链接到可穿戴设备提供商需要运行HTTP服务器,以便回调路由可以接收重定向。一旦链接,刷新令牌将保存在 `auth.json` 中,stdio模式可以无限期地从中同步。
---
## 仪表盘
在同一进程中从 `/` 提供服务。今日页面:
- **今日** — 当日的餐食,目标对比,水分,体重
- **日志** — 添加餐食,水分,体重,身体测量
- **食物**,**配方**,**批次** — 食物图
- **目标** — 宏量营养素边界,体重目标
- **实验室** — 面板,结果,趋势,每个生物标志物的关于卡片
- **趋势** — 每周汇总
- **可穿戴设备** — 提供商状态,睡眠/活动/准备度/每日读取
- **洞察** — `correlate` 用户界面
- **设置** — 令牌,时区,主题
基于TanStack Router + Query,Kumo UI在Tailwind v4上,以及Recharts。暗模式默认跟随您的操作系统;您可以在设置中固定它。
---
## 配置
优先级:CLI标志 > 环境变量 > JSON配置文件 > 默认值。
| 环境变量 | 目的 | 默认值 |
|---|---|---|
| `HEALTH_MCP_TOKEN` | 承载令牌。绑定到环回以外的地址时需要。 | 未设置(仅限环回) |
| `HEALTH_MCP_PORT` | HTTP端口 | `7777` |
| `HEALTH_MCP_HOST` | 绑定主机 | `127.0.0.1` |
| `HEALTH_MCP_DATA_DIR` | `data.db` 和 `auth.json` 的存储目录 | `~/.health-mcp` |
| `HEALTH_MCP_TZ` | 用于日桶查询的IANA时区 | 系统时区 |
| `HEALTH_MCP_WHOOP_CLIENT_ID` / `_SECRET` | Whoop OAuth应用凭证 | — |
| `HEALTH_MCP_OURA_CLIENT_ID` / `_SECRET` | Oura OAuth应用凭证 | — |
| `HEALTH_MCP_USDA_API_KEY` | 启用USDA食品数据中心远程搜索 | 本地搜索仅限 |
| `HEALTH_MCP_DASHBOARD` | 在 `/` 提供仪表盘 | `true` |
| `HEALTH_MCP_LOG_LEVEL` | `debug` / `info` / `warn` / `error` | `info` |
每个标志、每个环境变量、JSON配置文件架构和启动时强制执行的安全不变性都在 [docs/CONFIGURATION.md](./docs/CONFIGURATION.md).
---
## 隐私和安全
服务器构建为关闭失败。
- 环回是唯一安全的默认设置。要绑定到其他地方,您必须将 `HEALTH_MCP_TOKEN` 设置为32+个字符的高熵字符串(`openssl rand -hex 32`);否则服务器拒绝启动,没有软回退。
- `data.db` 和 `auth.json` 在 `0700` 父目录内以 `0600` 创建。宽松模式除非传递 `--allow-insecure-db` / `--allow-insecure-auth`,否则拒绝打开。
- 可穿戴设备OAuth凭证存储在 `~/.health-mcp/auth.json` 中,与 `data.db` 分开,因此 `health-mcp export` 可以在不泄露提供商令牌的情况下提供数据库。
- 提供商如Whoop在每次使用时都会轮换刷新令牌。身份验证存储序列化每个提供商的刷新令牌,因此两个并发的401不能同时使用相同的令牌并锁定您。
- OAuth回调使用具有10分钟到期时间和单个使用一次性非ces的HMAC签名状态有效载荷。
这些保护措施涵盖了什么,不保护什么,以及如何安全地将服务器暴露在本地主机之外(TLS终止隧道;检查医生输出)都在 [docs/SECURITY.md](./docs/SECURITY.md).
---
## 它是如何构建的
一个Node进程。一个Hono应用将MCP Streamable-HTTP传输安装在 `/mcp`,REST镜像安装在 `/api/*`,可穿戴设备OAuth回调安装在 `/auth/wearable/callback`,以及仪表盘SPA安装在 `/`。存储是通过better-sqlite3使用SQLite,`journal_mode=WAL` 和 `foreign_keys=ON`。所有业务逻辑都位于 `apps/server/src/services/*.ts`;MCP工具处理程序和REST路由是薄的Zod验证包装器,委托给它们。
在HTTP模式下,cron作业(默认为 `*/30 * * * *`,可配置)为每个链接的提供商调用 `syncWearables()`。stdio模式跳过调度器;代理按需调用 `sync_wearables`。
服务分解、传输管道和能力门控机制在 [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md).
---
## 工具表面
大约60种工具。`discover_capabilities` 返回按区域分组的实时目录,具有当前启用标志,代理可以先调用它而不是猜测可用性。
<details>
<summary>显示所有工具名称</summary>
```
ping, discover_capabilities
# 食品
search_food, search_foods, lookup_barcode, get_food
create_custom_food, bulk_upsert_custom_foods, update_custom_food, delete_custom_food
# 餐食
log_meal, list_meals, get_meal, update_meal, delete_meal, undo_last_meal,
add_meal_component, update_meal_component, remove_meal_component
# 配方 + 批次
create_recipe, update_recipe, delete_recipe, list_recipes, get_recipe
create_batch, list_batches, get_batch, archive_batch, delete_batch
# 记忆餐食(读取工具在您保存一个之前隐藏)
remember_meal, list_remembered_meals, get_remembered_meal,
update_remembered_meal, forget_meal, log_remembered_meal
# 简单日志
log_hydration, list_hydration, delete_hydration
log_weight, list_weight, delete_weight
log_measurement, list_measurements, delete_measurement
get_goals, set_goals
# 汇总
daily_summary, weekly_summary, range_summary
# 生物标志物 + 实验室
search_biomarker, get_biomarker, create_custom_biomarker, update_biomarker, set_optimal_range
log_lab_panel, log_lab_result, list_lab_results, latest_biomarkers, biomarker_trend
list_lab_panels, get_lab_panel, delete_lab_result, delete_lab_panel
# 洞察(隐藏直到 ≥7 天摄入量 AND (≥1 wearable_daily 行 OR ≥3 lab_results))
correlate, list_correlate_metrics
# 可穿戴设备(大多数在链接提供商之前隐藏)
wearables_list_providers, wearables_status,
wearable_connect_url, wearable_disconnect, sync_wearables,
wearable_sleep, wearable_activity, wearable_readiness, wearable_daily, wearable_metric_minutes,
set_activity_type_map
# Whoop(链接后隐藏)
whoop_recovery, whoop_cycles, whoop_sleep_raw, whoop_workouts_raw,
whoop_profile, whoop_body_measurement
```
</details>
能力门控隐藏了代理当前无法使用的工具,因此表面保持较小。可穿戴读取在链接提供商之前保持不可见;`correlate` 在值得关联的数据出现之前保持不可见。具有参数、返回形状和门控规则的完整目录在 [docs/MCP.md](./docs/MCP.md).
---
## 文档
| 文档 | 涵盖内容 |
|---|---|
| [架构](./docs/ARCHITECTURE.md) | 进程布局、传输、服务层、调度器 |
| [配置](./docs/CONFIGURATION.md) | 标志、环境变量、JSON配置、子命令、启动不变性 |
| [MCP工具](./docs/MCP.md) | 工具目录、能力门控、项目形状、代理客户端线路 |
| [REST API](./docs/API.md) | 仪表盘使用的 `/api/*` 镜像 |
| [数据模型](./docs/DATA_MODEL.md) | SQLite模式、索引、原始和标准化可穿戴设备拆分 |
| [生物标志物](./docs/BIOMARKERS.md) | 三层范围模型、状态行走、单位转换表 |
| [可穿戴设备](./docs/WEARABLES.md) | 提供商接口、OAuth流程、刷新轮换、提供商矩阵 |
| [安全](./docs/SECURITY.md) | 承载认证、环回规则、文件模式、OAuth状态、威胁模型 |
| [发布](./docs/RELEASING.md) | 版本提升 → 标签 → npm(OIDC)+ GHCR,都来自一个Actions运行 |
---
## 贡献
欢迎提出问题和PR。
```bash
pnpm install
pnpm typecheck && pnpm lint && pnpm test
```
一些基本规则:
- 业务逻辑位于 `apps/server/src/services/`。MCP工具(`src/mcp/tools/`)和REST路由(`src/rest/`)是薄包装器。不要在处理程序中放置逻辑。
- 迁移是检入的TypeScript模块,位于 `apps/server/src/db/sql/000N-*.ts`。仅向前。
- 共享Zod模式位于 `packages/shared`。服务器和仪表盘对此达成一致。
- 新服务需要一个Vitest案例(`*.test.ts`)或通过集成套件(`apps/server/src/integration.test.ts`)的覆盖。
- 在推送之前运行 `pnpm lint:fix` — Biome。
添加新的可穿戴设备提供商是一项自成体系的工作:创建 `apps/server/src/wearables/providers/<id>/`,添加带有原始镜像表的迁移,在可穿戴设备注册表中注册。标准化读取工具会自动拾取它。[docs/WEARABLES.md](./docs/WEARABLES.md#adding-a-new-provider) 中的演练。
切割发布是一个一键的GitHub Actions运行 — 提升、标记、npm发布和GHCR标签一气呵成。参见 [docs/RELEASING.md](./docs/RELEASING.md).
---
## 状态
个人项目,积极开发中。数据模型稳定,适用于营养、生物标志物和Whoop / Oura同步;迁移仅向前,启动时运行。期待工具参数和仪表盘路由出现重大变化,直到标记为 `1.0`。如果某些问题阻碍了您,请提一个问题。
这是一个个人使用工具,而不是医疗建议或医疗设备。它提供的值、范围和相关性用于自我量化,而不是诊断。
---
## 技术
节点 ≥ 20 · pnpm · TypeScript(ESM,严格)· Hono · `@modelcontextprotocol/sdk` v1 · better-sqlite3 · Zod · croner · Vitest · Biome。
仪表盘:Vite · React 18 · TanStack Router + Query · Tailwind v4 · Kumo UI · Recharts。
---
## 许可
[MIT](./LICENSE).