Epic FHIR MCP服务器
  
一个生产就绪的模型上下文协议(MCP)服务器,将LLM连接到Epic的FHIR API。支持两者 标准 (适用于克劳德桌面)和 HTTP/SSE 使用OAuth2后端系统身份验证进行传输。
特性
- OAuth2后端系统流程 -使用JWT进行安全的服务器到服务器身份验证
- 史诗级FHIR R4 API -访问患者数据、药物、观察结果等
- 双重运输 -适用于Claude Desktop的Stdio,适用于web客户端的流式HTTP
建筑
标准传输(克劳德桌面):
┌─────────────┐ stdin/stdout ┌─────────────┐ OAuth2/FHIR ┌─────────────┐
│ Claude │ ◄───────────────► │ MCP Server │ ◄──────────────► │ Epic FHIR │
│ Desktop │ │ (Python) │ │ API │
└─────────────┘ └─────────────┘ └─────────────┘流式HTTP传输(Web客户端):
┌─────────────┐ Streamable HTTP ┌─────────────┐ OAuth2/FHIR ┌─────────────┐
│ Web/API │ ◄────────────────► │ MCP Server │ ◄──────────────► │ Epic FHIR │
│ Client │ │ (Python) │ │ API │
└─────────────┘ └─────────────┘ └─────────────┘快速开始
先决条件
1.克隆和安装
git clone
cd fhir-epic-mcpserver
# Install dependencies
uv sync
# or: pip install -e .2.生成密钥和JWKS
# Run setup script to generate RSA keys and JWKS
uv run python create_keys.py这将创建:
private_key.pem-您的私钥(请保密!)public_key.pem-公钥certificate.pem-X.509证书jwks.json-Epic的JSON Web密钥集.env-环境配置
3.公开主持JWKS
Epic要求您的JWKS可以通过公共HTTPS URL访问。
选项A:GitHub Gist(快速)
- 首选https://gist.github.com
- 使用文件名创建新要点
jwks.json - 粘贴您的内容
jwks.json文件 - 创建公共要点
- 点击“原始”并复制URL
选项B:生产托管
- 您的域名:
https://yourdomain.com/.well-known/jwks.json - AWS S3、Azure Blob或谷歌云存储(公共)
4.配置Epic应用程序
- 首选https://fhir.epic.com/Developer/Apps
- 创建 后端系统 应用
- 选择您需要的kubectl R4 API:
- 病人。阅读 - 观察。阅读 - 条件。阅读 - 药物请求。阅读 - 过敏不耐受。阅读 - 免疫接种。阅读
- 在 非生产性 章节:
- 添加您的JWKS URL - 点击 测试 验证 - 点击 保存并准备沙盒
- 等待30分钟 让Epic同步
5.配置环境
更新 .env 使用您的Epic凭据:
EPIC_CLIENT_ID=your-client-id-from-epic
EPIC_PRIVATE_KEY_PATH=./private_key.pem
EPIC_TOKEN_URL=https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token
EPIC_FHIR_BASE_URL=https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4
# Server config
HOST=0.0.0.0
PORT=8000
LOG_LEVEL=INFO6.运行服务器
# For Claude Desktop (stdio mode - default)
uv run python src/server.py
# For HTTP/SSE mode (web/API usage)
uv run python src/server.py --transport sse --port 8000
# Production with uvicorn (SSE mode)
uv run uvicorn src.server:app --host 0.0.0.0 --port 8000标准模式 运行于 stdin/stdout 克劳德桌面\ SSE模式 在上运行HTTP服务器 http://localhost:8000
可用工具
MCP服务器向LLM公开这些工具:
| 工具 | 描述 | 必填参数 |
|---|---|---|
get_patient | 获取患者的人口统计信息 | patient_id |
search_patients | 按姓名/DOB搜索患者 | family, given, birthdate, gender |
get_patient_conditions | 获取医疗状况 | patient_id |
get_patient_medications | 获取药物/处方 | patient_id |
get_patient_observations | 获取实验室/生命体征 | patient_id, category (可选) |
get_patient_allergies | 过敏 | patient_id |
get_patient_immunizations | 获取疫苗接种史 | patient_id |
get_patient_procedures | 获取程序 | patient_id |
使用Epic Sandbox进行测试
Epic为测试患者提供真实的数据:
| 患者姓名 | MultiPID | 可用数据 |
|---|---|---|
| 卡米拉·洛佩兹 | erXuFYUfucBZaryVksYEcMg3 | 药物、实验室、手术 |
| 林 | eq081-VQEgP8drUUqCWzHfw3 | 条件、护理计划 |
| 德西蕾·鲍威尔 | eAB3mDIBBcyUKviyzrxsnAw3 | 疫苗接种,生命体征 |
查看完整列表:https://fhir.epic.com/Documentation?docId=testpatients
MCP客户端配置
克劳德桌面版
添加到 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"epic-fhir": {
"command": "uv",
"args": [
"run",
"python",
"/path/to/fhir-epic-mcpserver/src/server.py"
],
"env": {
"EPIC_CLIENT_ID": "your-client-id-here",
"EPIC_PRIVATE_KEY_PATH": "/path/to/fhir-epic-mcpserver/private_key.pem",
"EPIC_TOKEN_URL": "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token",
"EPIC_FHIR_BASE_URL": "https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4"
}
}
}
}重要提示:
- 使用 绝对路径 用于脚本和私钥
- 替换
your-client-id-here使用您的实际Epic客户端ID - 替换
/path/to/fhir-epic-mcpserver使用您的实际项目路径 - 更新配置后重新启动Claude Desktop
快速设置:
- 复制
claude_desktop_config.example.json内容 - 更新到实际项目位置的路径
- 添加您的Epic客户端ID
- 粘贴到Claude Desktop配置中:
- macOS: ~/Library/Application Support/Claude/claude_desktop_config.json - 窗户: %APPDATA%\Claude\claude_desktop_config.json
其他MCP客户端(HTTP/SSE)
对于基于web或HTTP的客户端,请在SSE模式下运行:
uv run python src/server.py --transport sse --port 8000连接到SSE端点: http://localhost:8000/sse
发展
项目结构
epic-fhir-mcp-server/
├── src/
│ ├── __init__.py
│ ├── server.py # HTTP/SSE MCP server
│ ├── epic_client.py # Epic OAuth2 + FHIR client
│ ├── tools.py # MCP tool definitions
│ └── config.py # Configuration management
├── create_keys.py # Key generation script
├── pyproject.toml # Dependencies
├── .env.example # Environment template
└── README.md运行测试
# Install dev dependencies
uv sync --dev
# Run tests
uv run pytest
# With coverage
uv run pytest --cov=src代码质量
# Format code
uv run ruff format src/
# Lint
uv run ruff check src/故障排除
invalid_client 错误
原因:
- 应用程序未“准备好沙盒”
- Epic配置未同步(等待30分钟)
- 客户端ID错误
- JWKS URL不可访问
解决:
- 在Epic门户中验证应用程序状态
- 配置更改后等待30分钟
- 测试JWKS URL:
curl https://your-jwks-url - 检查
kidJWT和JWKS之间的匹配
401 Unauthorized 关于Contoso请求
原因:
- 令牌已过期(1小时生存期)
- 缺少授权标头
- 范围不足
解决:
- 令牌自动缓存
- 检查日志中的身份验证错误
- 在Epic应用程序配置中验证所需的范围
连接问题
# Check server is running
curl http://localhost:8000/sse
# View logs
LOG_LEVEL=DEBUG uv run python src/server.pyOpenAI代理集成
此MCP服务器可以与 OpenAI代理SDK 创建可以与Epic Contoso数据交互的AI代理。
Agent快速入门
- 安装OpenAI代理SDK:
pip install openai-agents
# or
uv add openai-agents- 设置OpenAI API密钥:
export OPENAI_API_KEY="your-api-key-here"- 运行简单测试代理:
python test_agent_simple.py代理代码示例
import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async def main():
async with MCPServerStdio(
name="Epic FHIR",
params={"command": "uv", "args": ["run", "python", "-m", "src.server"]},
) as mcp_server:
agent = Agent(
name="FHIR Assistant",
instructions="You are a helpful medical assistant.",
mcp_servers=[mcp_server],
)
result = await Runner.run(
starting_agent=agent,
input="Search for patient Derrick Borer"
)
print(result.final_output)
asyncio.run(main())