Skip to main content
Glama
README.md
# a207-lis-mcp —— M2 检验数据

CKDNutri / NFYY038 Wave 1 交付包。为儿童慢性肾脏病场景提供检验面板查询、危急值独立通道、单指标趋势与新增采样写入。

技术栈:FastMCP ≥2.0 + pydantic ≥2 + Python 3.13,stdio 传输。

## 铁律遵循

- 不 import 任何其他 `a207-*` 包,不向其他 MCP 发起调用。所有入参为显式字段,由调度 Agent 从 PCP 取值后传入。
- `core.py` / `models.py` / `views.py` / `store.py` / `reference.py` 不依赖 fastmcp,未安装 fastmcp 也能跑 `tests/test_tools.py`。
- 单位与 `contracts/pcp-schema.json` 锁死:Scr μmol/L,K/P/Ca/Na/Cl/BUN/HCO3 mmol/L,Alb/Hb g/L,iPTH pg/mL,UA μmol/L,eGFR mL/min/1.73m²。写入口对 mg/dL、g/dL 口径做归一化。
- 写操作带 `caller` 校验,越权返回 `{"ok": false, "error": "FORBIDDEN", "detail": "..."}`。

## 权限(需求文档 §7 权限矩阵)

| caller | get_labs | get_critical_values | get_lab_trend | upsert_lab_result |
|---|---|---|---|---|
| doctor_assistant | 全量 | 允许 | 允许 | **允许写** |
| risk_warning | 全量 | 允许 | 允许 | 拒绝 |
| parent_assistant | 受限视图 | 拒绝 | 拒绝 | 拒绝 |
| nutritionist | 拒绝 | 拒绝 | 拒绝 | 拒绝 |
| child_companion | 拒绝 | 拒绝 | 拒绝 | 拒绝 |
| orchestrator | 拒绝 | 拒绝 | 拒绝 | 拒绝 |

家长受限视图只返回最近一次 K / P / 白蛋白 / 血红蛋白的**趋势方向(↑ ↓ →)**、**是否在儿童参考区间内**与**危急标注**,不返回任何原始数值。这是"能不能吃西瓜"类问题能个体化回答、又不越界暴露化验单的前提。

## 工具

### `get_labs(patient_id, caller="doctor_assistant")`
按报告日期升序返回全部检验面板。每个指标附单位、儿童年龄别参考区间上下限、状态判定(`critical_high` / `high` / `in_range` / `low` / `critical_low`)。`caller=parent_assistant` 走受限视图。

### `get_critical_values(patient_id, caller="risk_warning")`
危急值独立通道,扫描最近一次采样。内置阈值:K⁺ > 6.5、K⁺ < 2.8、Hb < 60、Ca < 1.60、Ca > 3.50、Na < 120、Na > 160、P > 3.20、HCO₃⁻ < 12。命中时 `next_action` 提示编排层走通知链路。

### `get_lab_trend(patient_id, analyte, caller="doctor_assistant", window_days=None)`
单指标时间序列,含环比绝对差、环比百分比、最小二乘拟合的每 30 天斜率与方向。`analyte` 取契约字段名,如 `scr_umol_L`、`k_mmol_L`、`hb_g_L`。

### `upsert_lab_result(patient_id, caller, lab, write_mode=True)`
新增一条采样。写权**仅** `doctor_assistant`(MX-3)。`lab` 走 pydantic 白名单校验,未声明字段与越界数值一律拒绝。成功返回 `recommend_reevaluate: true`,编排层据此**强制**触发风险规则重评;若新值命中危急阈值,`notify_action` 同时给出通知动作。

`write_mode=False` 为回滚模式:完成校验、单位归一化与危急值预演,但不落盘。

### `list_known_patients()`
列出本数据集覆盖的 patient_id,供跨包联调核对。

## 数据

`data/labs.json` 由 `data/generate.py` 以固定 seed(20260808)程序化生成,重复运行结果一致,产物随包提交。

- 34 例患儿、105 次采样,patient_id `P0001`–`P0034`,格式匹配 PCP 契约的 `^P[0-9]{4,}$`
- 覆盖分期 G2 / G3a / G3b / G4 / G5 × 透析方式 none / hemodialysis / peritoneal × 年龄带 1-3 / 4-6 / 7-12 / 13-17
- 每例 2–4 次跨月度采样,随时间轻度进展
- 先按分期抽取 eGFR,再用 Schwartz 床边公式反解肌酐,保证分期与肌酐互不矛盾;血钾在血透例偏高(透析前采样蓄积)、白蛋白在腹透例偏低(腹透液蛋白丢失)
- 强制置入 3 例危急值供链路测试:P0028 K⁺ 6.9 mmol/L、P0031 Hb 55 g/L、P0023 Ca 1.52 mmol/L

写入落盘到 `data/labs_store.json`(基线 `labs.json` 保持只读)。数据目录解析顺序:环境变量 `A207_LIS_DATA_DIR` → 包内 `data/` → 仓库根 `data/`。

重新生成:

```bash
python data/generate.py
```

## 自测

```bash
python -m py_compile src/a207_lis_mcp/*.py
python tests/test_tools.py
```

31 项断言,覆盖权限矩阵、受限视图零数值泄露、危急值命中、单位归一化、白名单校验、越权无副作用、零跨包引用。写操作跑在临时目录,不污染提交产物。

## 启动

```bash
fastmcp dev src/a207_lis_mcp/server.py
```

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct operation: one write (upsert_lab_result), one patient listing (list_known_patients), and three distinct read views (get_labs for all panels, get_critical_values for urgent flags, get_lab_trend for single-analyte time series). No two tools overlap in purpose; the descriptions clearly separate them.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: upsert_lab_result, list_known_patients, get_labs, get_critical_values, get_lab_trend. The verbs (upsert, list, get) are appropriate for their actions, and the nouns are descriptive and consistent.

Tool Count5/5

Five tools is a well-scoped size for a LIS MCP server. It covers the essential operations—write, patient lookup, general read, critical value alert, and trend analysis—without unnecessary redundancy or overwhelming the agent.

Completeness4/5

The tool set covers the core LIS lifecycle: inserting/updating results, retrieving patient panels, accessing critical values, and analyzing trends. The only minor gaps are lack of a delete operation and no granular single-result fetch by ID, but these are likely intentional and not critical for typical workflows.

Maintenance

ActivityMaintained
ResponsivenessSyncing