MCP Guardrail Patterns for Healthcare AI

The security layer between AI agents and clinical data.
PHI redaction, audit trails, step-up auth — one proxy for any FHIR server.

What the AI Agent Requested
Patient: Maria Elena Rivera
MRN: MRN-2026-4471
Phone: 617-555-0198
Address: 123 Clinical Ave, Boston, MA
DOB: 1985-03-15
What the AI Agent Received
Patient: Rivera, M. E.
MRN: ***4471
Phone: [Redacted]
Address: Boston, MA
DOB: 1985
AuditEvent: READ Patient/aee09834 by Agent/demo-agent at | Tenant: hospital-a

How This Compares

Feature This Project AWS HealthLake MCP Medplum MCP Raw FHIR
Works with any FHIR server HealthLake only Medplum only
PHI redaction on reads
Immutable audit trail CloudTrail Partial
Step-up auth for writes IAM Medplum auth
Human-in-the-loop
Setup time 10 seconds 30+ min 15+ min Varies

The Story: What Happens When an AI Agent Tries to Write Clinical Data?

1. Read Patient Record
PHI redacted: identifiers masked, addresses stripped, telecom hidden. Agent only sees safe data.
2. Propose Observation
Agent calls $validate. Structural validation gate ensures the resource is well-formed before anything else.
3. Permission DENIES
R6 Permission $evaluate returns deny with reasoning. No active rules = default deny. Agent explains why.
4. Policy Change + Re-evaluate
Treatment-purpose permit rule created. Re-evaluation returns permit with reasoning showing which rule matched.
5. Step-up Auth + Human Gate
HMAC-SHA256 token issued (128-bit nonce, 5-min TTL). Clinical write requires X-Human-Confirmed header.
6. Commit + Audit Trail
Write committed. Every step recorded in immutable, append-only AuditEvent trail. Full accountability.

Security Patterns

What's real: Mandatory tenant isolation on every query, HMAC-SHA256 step-up tokens for writes, ETag/If-Match concurrency control, OAuth 2.1 with PKCE (S256). Append-only audit trail with database-level immutability enforcement.

10 MCP Tools

Read tools add _mcp_summary with reasoning, clinical context, and limitations. Write tools use a propose/commit pattern: propose_write validates first, commit_write requires step-up auth. permission_evaluate returns human-readable reasoning.

Clinical Safety

Human-in-the-loop enforcement: clinical writes return HTTP 428 without explicit confirmation. HIPAA Safe Harbor de-identification. Medical disclaimer injection. PHI redaction on all read paths — the agent never sees raw patient data.

Architecture

Flask AppR6 REST facade at /r6/fhir/*
MCP ServerNode.js + TypeScript — 10 tools with reasoning
StorageJSON blobs in SQLite (demo) — not production
ValidationStructural only (required fields + value constraints)
FHIR VersionR6 v6.0.0-ballot3
Resources16 types (7 base + 9 R6 ballot)

R6-Specific Resources

PermissionR6 access control with $evaluate + reasoning
SubscriptionTopicRestructured pub/sub (storage + discovery)
DeviceAlertISO/IEEE 11073 device alarms (new in R6)
NutritionIntakeDietary tracking (new in R6)
$stats/$lastnStandard FHIR ops (since R4, not R6-specific)

Discovery Endpoints

/r6/fhir/metadata
CapabilityStatement
/r6/fhir/health
Liveness/Readiness
SMART Configuration
SMART-on-FHIR v2
Privacy Policy
Compliance & Terms