"""
Verify FDA approval status and return structured decision for PA workflows.
This tool provides the final determination for prior authorization.
"""
from typing import Dict, List, Any, Optional
from pydantic import BaseModel, Field
from core.app import mcp
from fastmcp import Context
class PADecision(BaseModel):
"""Prior authorization decision based on FDA verification."""
approved_for_pa: bool = Field(
description="Whether device meets FDA requirements for PA approval"
)
device_name: str = Field(description="Device name from FDA records")
manufacturer: str = Field(description="Manufacturer from FDA records")
fda_number: str = Field(description="FDA clearance/approval number")
fda_status: str = Field(
description="FDA regulatory status: cleared/approved/registered/not_found"
)
device_class: Optional[str] = Field(
default=None,
description="FDA device class (1, 2, or 3)"
)
meets_class_requirement: bool = Field(
default=True,
description="Whether device meets required class level"
)
is_otc: bool = Field(
default=False,
description="Whether device is OTC"
)
meets_otc_requirement: bool = Field(
default=True,
description="Whether device meets OTC/prescription requirement"
)
confidence: float = Field(
description="Confidence in verification (0-1)"
)
reasoning: str = Field(
description="Explanation of the decision"
)
recommendations: List[str] = Field(
default_factory=list,
description="Recommendations for PA approval or next steps"
)
warnings: List[str] = Field(
default_factory=list,
description="Any warnings or concerns"
)
@mcp.tool
async def verify_fda_status(
fda_results: List[Dict[str, Any]],
required_class: Optional[str] = None,
require_otc: Optional[bool] = None,
ctx: Context = None
) -> Dict[str, Any]:
"""
Verify FDA status and return structured decision for PA workflow.
This tool analyzes FDA search results and determines whether a device
meets regulatory requirements for prior authorization approval.
It provides clear reasoning and recommendations for the PA decision.
Args:
fda_results: List of FDA search results to verify
required_class: Required device class ("1", "2", or "3"), None allows any
require_otc: True=must be OTC, False=must be prescription, None=either
ctx: FastMCP context for logging
Returns:
Dictionary with approval status, reasoning, confidence,
and specific recommendations for the PA workflow
"""
if ctx:
await ctx.info(f"Verifying FDA status for {len(fda_results)} result(s)")
# Handle empty results
if not fda_results:
return PADecision(
approved_for_pa=False,
device_name="Unknown Device",
manufacturer="Unknown Manufacturer",
fda_number="None",
fda_status="not_found",
confidence=0.0,
reasoning="No FDA records found for this device",
recommendations=[
"Request FDA clearance/approval documentation from manufacturer",
"Verify device name and manufacturer spelling",
"Check if device is registered under different name"
],
warnings=["Device not found in FDA database"]
).model_dump()
# Select best result (highest confidence or first)
best_result = _select_best_result(fda_results)
# Create base decision
decision = PADecision(
approved_for_pa=False, # Will be set based on checks
device_name=best_result.get("device_name", "Unknown Device"),
manufacturer=best_result.get("manufacturer", best_result.get("applicant", "Unknown")),
fda_number=best_result.get("k_number") or best_result.get("pma_number") or best_result.get("fda_number", ""),
fda_status=_determine_fda_status(best_result),
device_class=str(best_result.get("device_class", "")),
is_otc=_is_otc_from_result(best_result),
confidence=best_result.get("match_confidence", best_result.get("confidence", 0.8)),
reasoning="",
recommendations=[],
warnings=[]
)
# Check class requirement
if required_class:
decision.meets_class_requirement = _check_class_requirement(
decision.device_class,
required_class
)
if not decision.meets_class_requirement:
decision.warnings.append(
f"Device is Class {decision.device_class}, but Class {required_class} is required"
)
# Check OTC requirement
if require_otc is not None:
decision.meets_otc_requirement = (decision.is_otc == require_otc)
if not decision.meets_otc_requirement:
if require_otc:
decision.warnings.append("OTC device required, but this is a prescription device")
else:
decision.warnings.append("Prescription device required, but this is OTC")
# Determine approval based on FDA status and requirements
approval_reasons = []
denial_reasons = []
# Check FDA clearance/approval
if decision.fda_status in ["cleared", "approved"]:
approval_reasons.append(f"Device is FDA {decision.fda_status}")
if decision.fda_number:
approval_reasons.append(f"FDA number: {decision.fda_number}")
elif decision.fda_status == "registered":
# Registration only (no clearance/approval)
denial_reasons.append("Device is only registered, not cleared/approved")
else:
denial_reasons.append("No valid FDA clearance or approval")
# Check class requirement
if required_class and not decision.meets_class_requirement:
denial_reasons.append(f"Does not meet Class {required_class} requirement")
elif decision.device_class:
approval_reasons.append(f"Device Class {decision.device_class} acceptable")
# Check OTC requirement
if require_otc is not None and not decision.meets_otc_requirement:
denial_reasons.append("Does not meet OTC/prescription requirement")
elif decision.is_otc:
approval_reasons.append("OTC device (no prescription required)")
else:
approval_reasons.append("Prescription device")
# Check confidence
if decision.confidence < 0.5:
decision.warnings.append("Low confidence in FDA match")
denial_reasons.append("Verification confidence too low")
# Make final determination
decision.approved_for_pa = (len(denial_reasons) == 0 and len(approval_reasons) > 0)
# Set reasoning
if decision.approved_for_pa:
decision.reasoning = (
f"Device meets FDA requirements for PA approval. " +
". ".join(approval_reasons)
)
decision.recommendations = [
"Proceed with prior authorization approval",
"Document FDA clearance number in PA records",
"Verify patient meets medical necessity criteria"
]
else:
decision.reasoning = (
f"Device does not meet FDA requirements. " +
". ".join(denial_reasons)
)
decision.recommendations = [
"Request additional FDA documentation",
"Consider alternative FDA-cleared devices",
"Review with medical director if medically necessary"
]
# Add specific recommendations based on device type
if decision.is_otc:
decision.recommendations.append(
"Note: OTC device does not require prescription for dispensing"
)
else:
decision.recommendations.append(
"Verify prescription from licensed healthcare provider"
)
if ctx:
status = "APPROVED" if decision.approved_for_pa else "DENIED"
await ctx.info(f"FDA verification {status}: {decision.reasoning}")
return decision.model_dump()
def _select_best_result(results: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Select the best FDA result from multiple matches."""
if not results:
return {}
# If results have confidence scores, sort by that
if "match_confidence" in results[0] or "confidence" in results[0]:
sorted_results = sorted(
results,
key=lambda x: x.get("match_confidence", x.get("confidence", 0)),
reverse=True
)
return sorted_results[0]
# Otherwise return first result
return results[0]
def _determine_fda_status(result: Dict[str, Any]) -> str:
"""Determine FDA regulatory status from result."""
# Check explicit status field
if "fda_status" in result:
return result["fda_status"]
# Check for K-number (510k clearance)
if result.get("k_number"):
return "cleared"
# Check for PMA number (PMA approval)
if result.get("pma_number"):
return "approved"
# Check decision code
decision_code = result.get("decision_code", "").upper()
if decision_code in ["SEKD", "SESD"]: # Substantially equivalent
return "cleared"
elif decision_code in ["APPR"]: # Approved
return "approved"
# Check for UDI only
if result.get("udi") and not result.get("k_number") and not result.get("pma_number"):
return "registered"
return "unknown"
def _is_otc_from_result(result: Dict[str, Any]) -> bool:
"""Determine if device is OTC from FDA result."""
# Check explicit OTC flag
if "is_otc" in result:
return result["is_otc"]
# Check product code
product_code = result.get("product_code", "")
if product_code == "QUH": # OTC hearing aid code
return True
# Check device name
device_name = result.get("device_name", "").lower()
if "otc" in device_name or "over-the-counter" in device_name:
return True
# Check regulation description
reg_desc = result.get("regulation_description", "").lower()
if "over-the-counter" in reg_desc:
return True
return False
def _check_class_requirement(device_class: str, required_class: str) -> bool:
"""Check if device meets class requirement."""
if not device_class or not required_class:
return True # No requirement or no class info
try:
device_class_num = int(device_class)
required_class_num = int(required_class)
# Device class must be equal to or less than required
# (Class 1 is lowest risk, Class 3 is highest)
return device_class_num <= required_class_num
except:
return True # Can't compare, assume OK