MCPDischarge
MCPDischarge — 부서 간 MCP 상호 운용성
EHR × 약국 × 청구 | RBAC | PHI 경계 | FastMCP
CitiusTech 생성형 AI & 에이전트 AI 교육 — 프로젝트 5
기존 API가 해결할 수 없는 문제
환자가 퇴원할 준비가 되었습니다. 데이터는 공통 프로토콜을 공유한 적이 없는 세 부서 간에 흘러야 합니다:
Traditional workflow (45 minutes, 15 manual handoffs):
Ward nurse → prints discharge note
Ward nurse → phones pharmacy to check drug availability
Pharmacy → calls back 2 hours later (drug out of stock)
Nurse → calls doctor to re-prescribe
Doctor → updates chart
Nurse → re-contacts pharmacy
Pharmacy → dispenses (brand name ≠ generic name — wrong drug dispensed?)
Nurse → separately calls billing department
Billing clerk → manually re-enters ICD-10 codes from printed note
Billing clerk → can see full medication list including controlled substances (HIPAA risk)
Patient → waits, often 4–6 hours post-clinical-readinessMCP(Model Context Protocol)는 표준화되고 유형이 지정된 RBAC 강제 도구 호출 계층을 통해 이를 해결합니다:
MCP workflow (< 1 second, automated):
DischargeAgent.EHR.get_discharge_medications() ← structured, not free text
DischargeAgent.Pharmacy.check_stock() ← semantic name matching
DischargeAgent.Pharmacy.get_alternative() ← out-of-stock resolution
DischargeAgent.EHR.get_billing_safe_summary() ← PHI stripped at source
DischargeAgent.Billing.generate_invoice() ← billing never sees clinical notesRelated MCP server: FHIR MCP Server
아키텍처
┌────────────────────────────────────────────────────────────────┐
│ Discharge Coordination Agent │
│ (MCP Client — role: discharge_coordinator) │
└────────┬───────────────────┬───────────────────┬──────────────┘
│ MCP calls │ MCP calls │ MCP calls
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ EHR MCP Server │ │ Pharmacy Server │ │ Billing Server │
│ (port 8001) │ │ (port 8002) │ │ (port 8003) │
│ │ │ │ │ │
│ Tools: │ │ Tools: │ │ Tools: │
│ • discharge_meds│ │ • check_stock │ │ • get_charges │
│ • diagnosis_cod │ │ • get_alternative│ │ • get_insurance │
│ • billing_safe │ │ • get_price │ │ • gen_invoice │
│ _summary │ │ • dispense_req │ │ │
│ [RBAC enforced] │ │ [RBAC enforced] │ │ [RBAC enforced] │
└─────────────────┘ └─────────────────┘ └─────────────────┘
PHI Boundary:
EHR → Billing path uses get_billing_safe_summary()
PHI fields blocked: name, DOB, MRN, discharge_note, attending_physician
Billing receives: ICD-10 codes, LOS, ward — non-PHI operational data onlyRBAC 정책 매트릭스
역할 | EHR 임상 노트 | EHR 처방 약물 | EHR 진단 코드 | 약국 | 청구 |
| ✓ | ✓ | ✓ | ✓ | ✓ |
| ✗ 차단됨 | ✗ 차단됨 | ✓ | 가격만 | ✓ |
| ✗ | ✓ | ✓ | ✓ | ✗ 차단됨 |
| ✓ | ✓ | ✓ | 재고 확인 | ✗ 차단됨 |
모든 도구 호출은 데이터를 반환하기 전에 호출자의 역할을 검증합니다. 권한이 없는 호출은 RBACError를 발생시키고 원격 측정 피드에 기록됩니다.
빠른 시작
1단계: 종속성 설치
pip install -r requirements.txt2단계: 데이터 생성
cd data/
python generate_dataset.py3단계: 서버 실행
FastMCP HTTP 서버 (프로덕션 스타일, 비동기 MCP 에이전트에 필요):
# Terminal 1:
python src/servers/mcp_servers.py --server ehr
# Terminal 2:
python src/servers/mcp_servers.py --server pharmacy
# Terminal 3:
python src/servers/mcp_servers.py --server billing또는 세 서버를 하나의 프로세스에서 실행 (3개의 백그라운드 스레드 시작):
python src/servers/mcp_servers.py --all직접 Python 실행 (HTTP 없음, 교육용):
from src.servers.ehr_server import EHRServer
ehr = EHRServer()
meds = ehr.get_discharge_medications("PAT-001", role="discharge_coordinator")4단계: 퇴원 에이전트 실행
python src/agents/discharge_agent.py PAT-001
python src/agents/discharge_agent.py PAT-0035단계: 전체 데모
python demo/demo.py # Runs 4 scenarios
python demo/demo.py --scenario 3 # RBAC violation only채팅 UI (React)
이 저장소에는 경량 FastAPI 게이트웨이를 호출하는 간단한 React 채팅 프론트엔드가 포함되어 있으며, 이 게이트웨이는 다시 MCP 서버를 호출합니다.
1) MCP 서버 시작 (SSE)
python src/servers/mcp_servers.py --all2) 채팅 게이트웨이 API 시작 (포트 8000)
copy .env.example .env # then fill in Azure OpenAI settings (optional)
python -m uvicorn src.gateway.chat_gateway:app --reload --port 80003) React 개발 서버 시작 (포트 5173)
cd frontend
npm install
npm run dev6단계: 평가
cd evaluation/
python eval_dashboard.py참고: 평가는 SSE를 통해 비동기 MCP 에이전트를 호출하므로 MCP 서버가 실행 중이어야 합니다 (3단계).
프로젝트 구조
mcpdischarge/
├── data/
│ ├── generate_dataset.py ← Run this first
│ ├── ehr_patients.json ← 6 patient records with discharge medications
│ ├── pharmacy_inventory.json ← 17 drugs (4 out of stock, aliases table)
│ ├── billing_rate_cards.json ← 15 charge codes
│ ├── insurance_contracts.json ← 2 insurer contracts
│ ├── patient_insurance_map.json ← Patient → insurer mappings
│ ├── icd10_billing_codes.json ← ICD-10 → DRG billing mappings
│ └── rbac_policies.json ← RBAC matrix (role → server → tools)
│
├── src/
│ ├── servers/
│ │ └── mcp_servers.py ← EHRServer, PharmacyServer, BillingServer + FastMCP wrappers
│ └── agents/
│ └── discharge_agent.py ← DischargeCoordinationAgent + WorkflowMetrics
│
├── evaluation/
│ ├── eval_dashboard.py
│ ├── 01_manual_vs_mcp.png
│ ├── 02_rbac_telemetry.png
│ └── 03_data_integrity.png
│
├── demo/
│ └── demo.py ← 4 scenarios + 2 limitations
│
├── configs/
│ ├── fastmcp_deployment.md ← FastMCP HTTP server setup
│ ├── azure_foundry_mcp.md ← Azure AI Foundry MCP integration
│ └── rbac_design.md ← RBAC policy design guide
│
└── README.md주입된 챌린지 패턴
패턴 | 환자 | 약물 | 주입된 문제 |
| PAT-001 | Dapagliflozin/Farxiga | EHR은 브랜드명 사용; 약국은 제네릭 저장 |
| PAT-001 | Furosemide 40mg | 재고=0; MCP가 대체제로 Torsemide 제시 |
| PAT-003 | Humira/Adalimumab | 브랜드 품절; 바이오시밀러 Exemptia 발견 |
| PAT-004 | Tafamidis/Vyndamax | 희귀 질환 약물 — 대체제 없음; 에스컬레이션 |
| PAT-005 | Osimertinib/Tagrisso | 전문 의약품 — 중앙 약국 주문 |
| PAT-002 | Semaglutide 0.5mg | EHR 유지 용량 vs 처방집 시작 용량 0.25mg |
| PAT-006 | Modafinil Schedule H | 청구 부서는 향정신성 의약품 세부 정보를 보아서는 안 됨 |
| 전체 | — | 청구 송장 발행 전 5개의 PHI 필드 차단 |
세 가지 MCP 서버 (상세)
EHR 서버
PHI 민감 도구 (임상 역할만):
get_patient_discharge_summary(patient_id, caller_role) # full clinical note
get_discharge_medications(patient_id, caller_role) # medication listPHI 안전 도구 (청구 포함 모든 역할):
get_diagnosis_codes(patient_id, caller_role) # ICD-10 only
get_admission_info(patient_id, caller_role) # LOS, ward, dates
get_billing_safe_summary(patient_id, caller_role) # strips PHI fieldsPHI 제거 (청구 부서에 대해 차단되는 항목):
PHI_FIELDS = {"name", "dob", "mrn", "discharge_note", "attending_physician"}
# Billing receives: patient_id, ward, admission_date, discharge_date, los_days, diagnosis_icd10약국 서버
의미론적 이름 확인:
# EHR says "Dapagliflozin" → Pharmacy stores as "Farxiga"
# MCP alias table: {"farxiga": "PH-001", "dapa": "PH-001", "sglt2 inhibitor": "PH-001"}
drug = _find_drug_by_name("Dapagliflozin") # → PH-001 (Dapagliflozin)
drug = _find_drug_by_name("Humira") # → PH-008 (Adalimumab, branded)용량 충돌 감지:
# EHR prescribes Semaglutide 0.5mg, formulary standard is 0.25mg starter
if queried_dose not in formulary_dose:
dose_conflict = True # triggers clinical review alert의미론적 일치 점수:
# score = word overlap / max(len(ehr_words), len(pharm_words))
# score < 0.85 → NAME_MISMATCH alert even if drug found
semantic_drug_match_score("Humira", "Adalimumab") # → 0.0 (no word overlap)
semantic_drug_match_score("Furosemide", "Furosemide") # → 1.0 (exact)청구 서버
송장 생성 (PHI 보호):
def generate_invoice(patient_id, billing_safe_ehr, drug_costs, ...):
# Verify PHI is stripped
for phi_field in PHI_FIELDS:
if phi_field in billing_safe_ehr:
raise PermissionError(f"PHI field '{phi_field}' in billing payload")
# Process invoice using only: ICD-10 + LOS + ward + drug pricesMCP vs 기존 API 비교
기능 | 기존 REST API | MCP 프로토콜 |
스키마 발견 | 정적 Swagger 문서 | 동적 도구 매니페스트 |
부서 간 호출 | 취약한 지점 간 연결 | 표준화된 도구 호출 |
RBAC 강제 | 앱 계층 (일관성 없음) | 프로토콜 계층 (보장됨) |
PHI 경계 | 수동 정책 | 도구별 강제 |
약물 이름 확인 | 하드코딩된 매핑 | 의미론적 별칭 테이블 |
품절 처리 | 수동 약국 콜백 | 자동 대체제 조회 |
원격 측정 | 사용자 정의 로깅 | 내장 도구 호출 추적 |
신규 부서 온보딩 | 새로운 API 통합 | 새로운 MCP 서버 등록 |
평가 결과 (6건의 환자 퇴원)
환자 | MCP 호출 | 성공 | 알림 | PHI 차단 |
PAT-001 HFrEF | 16 | 100% | 1 | 5개 필드 |
PAT-002 AKI | 11 | 100% | 1 | 5개 필드 |
PAT-003 RA | 13 | 100% | 2 | 5개 필드 |
PAT-004 ATTR | 14 | 100% | 2 | 5개 필드 |
PAT-005 NSCLC | 9 | 100% | 1 | 5개 필드 |
PAT-006 MS | 9 | 100% | 1 | 5개 필드 |
총계: 72건의 MCP 도구 호출 | 100% 성공 | 퇴원당 15건의 수동 인수인계 대체 | 사례당 약 45분 절약
FastMCP HTTP 배포
configs/fastmcp_deployment.md를 참조하세요. 주요 패턴:
from fastmcp import FastMCP
ehr_mcp = FastMCP("EHR-Server")
@ehr_mcp.tool()
def get_discharge_medications(patient_id: str, caller_role: str) -> dict:
"""Get discharge medication list from EHR."""
return EHRServer().get_discharge_medications(patient_id, caller_role)
# Run as HTTP SSE server
ehr_mcp.run(transport="sse", host="0.0.0.0", port=8001)에이전트는 MCP 클라이언트로 연결:
from mcp import ClientSession, StdioServerParameters
from mcp.client.sse import sse_client
async with sse_client("http://localhost:8001/sse") as (read, write):
async with ClientSession(read, write) as session:
result = await session.call_tool(
"get_discharge_medications",
{"patient_id": "PAT-001", "caller_role": "discharge_coordinator"}
)Azure AI Foundry 통합
configs/azure_foundry_mcp.md를 참조하세요. MCP 서버는 Foundry 도구로 등록됩니다:
from azure.ai.projects.models import McpToolDefinition
mcp_tools = [
McpToolDefinition(server_url="http://ehr-server:8001/sse", name="ehr-server"),
McpToolDefinition(server_url="http://pharmacy-server:8002/sse", name="pharmacy-server"),
McpToolDefinition(server_url="http://billing-server:8003/sse", name="billing-server"),
]
agent = client.agents.create_agent(
model="gpt-4o",
name="DischargeCoordinationAgent",
instructions=DISCHARGE_AGENT_SYSTEM_PROMPT,
tools=[t.as_tool_definition() for t in mcp_tools],
)CitiusTech 생성형 AI & 에이전트 AI 교육 프로그램 — 5개 프로젝트 중 5번째
This server cannot be deployed
Maintenance
Related MCP Connectors
Remote MCP for MCP consent scope receipt, structured receipts, audit logs, and reviewer-ready eviden
MCP gateway federating 22 biomedical MCP servers behind one endpoint: gnomAD, ClinVar, HPO, VEP.
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
Hosted MCP for denial, prior auth, reimbursement, workflow validation, batch scoring, and feedback.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables automated cross-department healthcare discharge coordination using MCP, integrating EHR, Pharmacy, and Billing with RBAC and PHI boundary enforcement.-
- FlicenseNot gradedqualityDmaintenanceA comprehensive MCP server that bridges AI applications with FHIR healthcare data systems, enabling patient data access, clinical data retrieval, and data quality assessment.4-
- AlicenseAqualityCmaintenanceMCP server for healthcare claims workflow scoring, validation, and feedback, supporting denial risk, prior authorization, and reimbursement assessment.8MIT
- FlicenseAqualityCmaintenanceA learning MCP server providing synthetic FHIR patient data with read tools and a gated write workflow (propose → human approve → commit) with structured audit logging.10-