内容
FHIR MCP 服务器
> **合成数据,仅用于教育和投资组合展示 — 非医疗设备 — 不用于临床实践。**
>
> - 患者数据由 **Synthea 生成**;本仓库 **不包含真实的受保护健康信息(PHI)**
> - **非医疗设备**;**不用于诊断、治疗、分诊或任何临床工作流程**
> - 仅用于教育和投资组合展示
> - 药物名称来自本地 FHIR `MedicationRequest` 记录(合成数据)— **仅供参考,非医疗建议**。v1 版本中 **没有外部药物 API**。
v1 只读工具 + 地基评估卡:一个 C#/.NET [MCP](https://modelcontextprotocol.io/) 服务器,允许 Claude 查询合成的 FHIR 患者数据,无需直接操作 FHIR。
## 问题
Claude Desktop 可以协调工具,但 FHIR R4 JSON 数据来说较为复杂(包含代码、引用和分页信息)。该服务器通过本地 **HAPI FHIR** 和 **Synthea** 数据,提供一个小的 **只读** 工具集,并返回干净的文本摘要 — 使模型能够通过工具输出保持准确,而不是自行生成不准确的信息。
## 架构
```mermaid
flowchart LR
Claude[ClaudeDesktop] -->|stdio MCP| Tools[医疗工具]
Tools --> 服务[临床查询服务]
服务 --> Fhir[FirelyFhir仓库]
Fhir --> HAPI[HAPI_Docker]
服务 --> 映射[映射摘要]
映射 --> Tools
```
原始 FHIR 数据不会离开映射层。工具仅负责协调;Firely 与 HAPI 交互。
## 技术栈
C# / .NET 10 · `ModelContextProtocol` 1.4.x(stdio)· Firely `Hl7.Fhir.R4` · HAPI FHIR(Docker)· Synthea · xUnit
## 快速开始
**前提条件:** .NET SDK 10、Docker Compose、curl(和 unzip)。Node.js 可选(MCP 检验器)。Claude Desktop 可选。**无需 Java** 即可顺利运行。
请优先使用 `http://127.0.0.1:8080/fhir` 而非 `localhost`(IPv6/`::1` 可能导致问题)。
1. 启动 HAPI:
```bash
docker compose up -d
```
2. 下载预构建的 Synthea FHIR R4 示例(ZIP 格式,无需 Java),并将 JSON 文件解压到 `data/sample-synthea-data/` 目录:
```bash
mkdir -p data/sample-synthea-data
curl -L -o /tmp/synthea_fhir_r4.zip \
"https://synthetichealth.github.io/synthea-sample-data/downloads/synthea_sample_data_fhir_r4_sep2019.zip"
unzip -o /tmp/synthea_fhir_r4.zip -d /tmp/synthea_fhir_r4
cp /tmp/synthea_fhir_r4/fhir/*.json data/sample-synthea-data/
```
**Windows(PowerShell):**
```powershell
New-Item -ItemType Directory -Force -Path data\sample-synthea-data | Out-Null
curl.exe -L -o $env:TEMP\synthea_fhir_r4.zip `
"https://synthetichealth.github.io/synthea-sample-data/downloads/synthea_sample_data_fhir_r4_sep2019.zip"
Expand-Archive -Force $env:TEMP\synthea_fhir_r4.zip $env:TEMP\synthea_fhir_r4
Copy-Item $env:TEMP\synthea_fhir_r4\fhir\*.json data\sample-synthea-data\
```
更多详细信息和 Java 生成替代方案,请参阅 [`data/README.md`](data/README.md)。
3. 将批量数据加载到 HAPI(官方示例 ZIP 文件不包含医院/医疗实践者 bundles — 加载器会自动跳过这些):
```powershell
powershell -ExecutionPolicy Bypass -File .\data\load-synthea.ps1
```
```bash
chmod +x data/load-synthea.sh && ./data/load-synthea.sh
```
4. 进行烟雾测试和单元测试:
```bash
dotnet run -- --smoke Harris
dotnet test fhir-mcp-server.Tests/fhir-mcp-server.Tests.csproj
```
5. 启动 MCP 服务器(stdio)或检验器:
```bash
dotnet build
npx @modelcontextprotocol/inspector dotnet exec bin/Debug/net10.0/fhir-mcp-server.dll
```
6. Claude Desktop(可选):绝对 `dotnet` 和 dll 文件路径,以及 `env.Fhir__BaseUrl=http://127.0.0.1:8080/fhir`。配置路径:Windows `%APPDATA%\Claude\…`,macOS `~/Library/Application Support/Claude/…`,Linux `~/.config/Claude/…`。
## 演示
**检验器(无 Claude):**
```bash
npx @modelcontextprotocol/inspector --cli \
dotnet exec bin/Debug/net10.0/fhir-mcp-server.dll \
--method tools/list
```
然后,使用部分姓名调用 `search_patients`(例如 `Harris`),获取返回的 FHIR id,并调用 `get_patient_summary` / `get_conditions` / `get_medications`。
**Claude Desktop — 尝试以下操作:**
> 查找患者 Harris,总结其信息,然后列出其活跃的疾病和当前的药物。
一个强大的演示运行会链接这些工具,而无需告知步骤。地基评估卡:[`evals/grounding-results.md`](evals/grounding-results.md)。还使用 **Cursor**(Composer)和本地 **Qwen2.5 7B** 客户端通过 LM Studio 进行了测试 — stdio MCP 是客户端无关的,不特定于 Claude Desktop。
## 安全
- 所有五个 MCP 工具都是 **只读** 的(`ReadOnly=true`,`Destructive=false`)— 无需通过 MCP 进行临床创建/更新/删除
- 响应是汇总的文本,而不是原始 FHIR JSON
- 缺失的数据会明确返回“未找到”— 服务器永远不会伪造数据
- 药物是本地 HAPI/Synthea FHIR 的显示名称 — **不是临床建议**;v1 中没有 OpenFDA/DrugBank/RxNorm API
- `data/load-synthea.ps1` 和 `data/load-synthea.sh` 将 bundles 发布到本地 HAPI **仅用于开发设置** — 它们不属于 MCP 工具表面
## 评估和地基
投资组合重点:**评估 + 人在环**,而不是“模型总是正确”。
权威评估卡:[`evals/grounding-results.md`](evals/grounding-results.md)(9 个提示)。
| 我们衡量的内容 | 我们 **不** 声称的内容 |
| --- | --- |
| Claude 的答案停留在 MCP 工具返回的内容内(地基) | 通过这些评估证明 FHIR→摘要映射是认证的(这是单元测试 + 烟雾测试) |
| 路由质量(额外的干净失败探测 vs. 编造数据) | 多次运行的统计显著性 |
**关闭标准:** 地基 **9/9** · 路由 **≥7/9 ok** · 标记为 `单次运行 · 模型 · 日期 · N=9`。
**人在环:** 地基保证数据;解释仍可能漂移(例如,不请自来的药物推断,年龄算术因出生年份猜测而出错)。查看文本,而不是工具 JSON。
**当前排行榜:** `单次运行 · 模型=Haiku · 日期=2026-07-18 · N=9` — 地基 **9/9** · 路由 **8/9 ok** (1 个嘈杂)。
## 项目布局
```
Fhir/ Firely 客户端 + 仓库
Mapping/ FHIR 资源 → 清洁摘要文本
Services/ 临床查询服务组合
Tools/ MCP 工具包装器(stdio)
data/ 加载脚本 + README(有效载荷被 gitignore)
evals/ 地基评估卡
fhir-mcp-server.Tests/ xUnit 单元测试
docker-compose.yml HAPI FHIR 在 :8080
```
## 许可证
[MIT](LICENSE)