Skip to main content
Glama

Medical Calculator MCP Service

apache_ii_calculator.py22.6 kB
""" APACHE II Score Calculator """ from typing import Dict, Any from medcalc import ( BaseCalculator, CalculatorInfo, Parameter, ParameterType, ValidationResult, CalculationResult, register_calculator ) from medcalc.utils import round_number @register_calculator("apache_ii") class ApacheIICalculator(BaseCalculator): """APACHE II评分计算器实现""" def get_info(self) -> CalculatorInfo: return CalculatorInfo( id=28, name="APACHE II Score", category="critical_care", description="Acute Physiology and Chronic Health Evaluation II score for ICU mortality prediction", parameters=[ Parameter( name="age", type=ParameterType.NUMERIC, required=True, min_value=0, max_value=120, description="Patient age in years" ), Parameter( name="temperature", type=ParameterType.NUMERIC, required=True, unit="°C", min_value=25, max_value=45, description="Rectal temperature in Celsius" ), Parameter( name="systolic_bp", type=ParameterType.NUMERIC, required=True, unit="mmHg", min_value=30, max_value=300, description="Systolic blood pressure in mmHg" ), Parameter( name="diastolic_bp", type=ParameterType.NUMERIC, required=True, unit="mmHg", min_value=20, max_value=200, description="Diastolic blood pressure in mmHg" ), Parameter( name="heart_rate", type=ParameterType.NUMERIC, required=True, unit="bpm", min_value=20, max_value=250, description="Heart rate in beats per minute" ), Parameter( name="respiratory_rate", type=ParameterType.NUMERIC, required=True, unit="breaths/min", min_value=5, max_value=80, description="Respiratory rate in breaths per minute" ), Parameter( name="fio2", type=ParameterType.NUMERIC, required=True, unit="%", min_value=21, max_value=100, description="Fraction of inspired oxygen percentage" ), Parameter( name="pao2", type=ParameterType.NUMERIC, required=False, unit="mmHg", min_value=20, max_value=500, description="Partial pressure of oxygen (required if FiO2 < 50%)" ), Parameter( name="aa_gradient", type=ParameterType.NUMERIC, required=False, unit="mmHg", min_value=0, max_value=700, description="Alveolar-arterial gradient (required if FiO2 >= 50%)" ), Parameter( name="ph", type=ParameterType.NUMERIC, required=True, min_value=6.5, max_value=8.0, description="Arterial pH" ), Parameter( name="sodium", type=ParameterType.NUMERIC, required=True, unit="mmol/L", min_value=100, max_value=200, description="Serum sodium in mmol/L" ), Parameter( name="potassium", type=ParameterType.NUMERIC, required=True, unit="mmol/L", min_value=1.0, max_value=10.0, description="Serum potassium in mmol/L" ), Parameter( name="creatinine", type=ParameterType.NUMERIC, required=True, unit="mg/dL", min_value=0.1, max_value=15.0, description="Serum creatinine in mg/dL" ), Parameter( name="hematocrit", type=ParameterType.NUMERIC, required=True, unit="%", min_value=10, max_value=70, description="Hematocrit percentage" ), Parameter( name="wbc", type=ParameterType.NUMERIC, required=True, unit="×10³/mm³", min_value=0.1, max_value=100, description="White blood cell count in thousands per cubic mm" ), Parameter( name="gcs", type=ParameterType.NUMERIC, required=True, min_value=3, max_value=15, description="Glasgow Coma Scale score" ), Parameter( name="acute_renal_failure", type=ParameterType.BOOLEAN, required=False, default=False, description="Presence of acute renal failure" ), Parameter( name="chronic_renal_failure", type=ParameterType.BOOLEAN, required=False, default=False, description="Presence of chronic renal failure" ), Parameter( name="organ_failure_immunocompromise", type=ParameterType.BOOLEAN, required=False, default=False, description="History of severe organ insufficiency or immunocompromised state" ), Parameter( name="surgery_type", type=ParameterType.CHOICE, required=False, choices=["none", "elective", "emergency"], default="none", description="Type of surgery (none, elective, emergency)" ) ] ) def validate_parameters(self, parameters: Dict[str, Any]) -> ValidationResult: """验证参数""" errors = [] warnings = [] # 必需参数列表 required_params = [ "age", "temperature", "systolic_bp", "diastolic_bp", "heart_rate", "respiratory_rate", "fio2", "ph", "sodium", "potassium", "creatinine", "hematocrit", "wbc", "gcs" ] # 检查必需参数 for param_name in required_params: if param_name not in parameters: errors.append(f"Missing required parameter: {param_name}") if errors: return ValidationResult(is_valid=False, errors=errors) # 验证数值范围 validations = [ ("age", 0, 120), ("temperature", 25, 45), ("systolic_bp", 30, 300), ("diastolic_bp", 20, 200), ("heart_rate", 20, 250), ("respiratory_rate", 5, 80), ("fio2", 21, 100), ("ph", 6.5, 8.0), ("sodium", 100, 200), ("potassium", 1.0, 10.0), ("creatinine", 0.1, 15.0), ("hematocrit", 10, 70), ("wbc", 0.1, 100), ("gcs", 3, 15) ] for param_name, min_val, max_val in validations: if param_name in parameters: value = parameters[param_name] if value is not None: if value < min_val: errors.append(f"{param_name}: Value {value} is below minimum {min_val}") if value > max_val: errors.append(f"{param_name}: Value {value} is above maximum {max_val}") # 可选参数验证 if "pao2" in parameters and parameters["pao2"] is not None: pao2 = parameters["pao2"] if pao2 < 20 or pao2 > 500: errors.append(f"pao2: Value {pao2} is out of range (20-500)") if "aa_gradient" in parameters and parameters["aa_gradient"] is not None: aa_gradient = parameters["aa_gradient"] if aa_gradient < 0 or aa_gradient > 700: errors.append(f"aa_gradient: Value {aa_gradient} is out of range (0-700)") # 验证选择类型参数 surgery_type = parameters.get("surgery_type", "none") if surgery_type not in ["none", "elective", "emergency"]: errors.append(f"surgery_type: Invalid choice '{surgery_type}'. Must be one of: ['none', 'elective', 'emergency']") # FiO2相关验证 fio2 = parameters.get("fio2") pao2 = parameters.get("pao2") aa_gradient = parameters.get("aa_gradient") if fio2 is not None: if fio2 < 50: if pao2 is None: errors.append("PaO2 is required when FiO2 < 50%") else: if aa_gradient is None: errors.append("A-a gradient is required when FiO2 >= 50%") # 肾功能验证 acute_renal = parameters.get("acute_renal_failure", False) chronic_renal = parameters.get("chronic_renal_failure", False) if acute_renal and chronic_renal: errors.append("Patient cannot have both acute and chronic renal failure") # 器官衰竭和手术类型验证 organ_failure = parameters.get("organ_failure_immunocompromise", False) surgery_type = parameters.get("surgery_type", "none") if organ_failure and surgery_type == "none": errors.append("Surgery type must be specified when organ failure/immunocompromise is present") return ValidationResult( is_valid=len(errors) == 0, errors=errors, warnings=warnings ) def calculate(self, parameters: Dict[str, Any]) -> CalculationResult: """计算APACHE II评分""" # 获取参数值 age = parameters["age"] temperature = parameters["temperature"] systolic_bp = parameters["systolic_bp"] diastolic_bp = parameters["diastolic_bp"] heart_rate = parameters["heart_rate"] respiratory_rate = parameters["respiratory_rate"] fio2 = parameters["fio2"] pao2 = parameters.get("pao2") aa_gradient = parameters.get("aa_gradient") ph = parameters["ph"] sodium = parameters["sodium"] potassium = parameters["potassium"] creatinine = parameters["creatinine"] hematocrit = parameters["hematocrit"] wbc = parameters["wbc"] gcs = parameters["gcs"] acute_renal_failure = parameters.get("acute_renal_failure", False) chronic_renal_failure = parameters.get("chronic_renal_failure", False) organ_failure_immunocompromise = parameters.get("organ_failure_immunocompromise", False) surgery_type = parameters.get("surgery_type", "none") score = 0 explanation_parts = [] # 1. 年龄评分 if age < 45: age_points = 0 elif 45 <= age <= 54: age_points = 2 elif 55 <= age <= 64: age_points = 3 elif 65 <= age <= 74: age_points = 5 else: # >= 75 age_points = 6 score += age_points explanation_parts.append(f"Age {age} years: +{age_points} points") # 2. 器官衰竭/免疫缺陷史 if organ_failure_immunocompromise: if surgery_type == "elective": organ_points = 2 elif surgery_type == "emergency": organ_points = 5 else: organ_points = 5 # nonoperative else: organ_points = 0 score += organ_points if organ_points > 0: explanation_parts.append(f"Organ failure/immunocompromise ({surgery_type}): +{organ_points} points") # 3. 体温评分 if temperature >= 41: temp_points = 4 elif 39 <= temperature < 41: temp_points = 3 elif 38.5 <= temperature < 39: temp_points = 1 elif 36 <= temperature < 38.5: temp_points = 0 elif 34 <= temperature < 36: temp_points = 1 elif 32 <= temperature < 34: temp_points = 2 elif 30 <= temperature < 32: temp_points = 3 else: # < 30 temp_points = 4 score += temp_points explanation_parts.append(f"Temperature {temperature}°C: +{temp_points} points") # 4. 平均动脉压 map_value = (2 * diastolic_bp + systolic_bp) / 3 if map_value >= 160: map_points = 4 elif 130 <= map_value < 160: map_points = 3 elif 110 <= map_value < 130: map_points = 2 elif 70 <= map_value < 110: map_points = 0 elif 50 <= map_value < 70: map_points = 2 elif 40 <= map_value < 50: map_points = 3 else: # < 40 map_points = 4 score += map_points explanation_parts.append(f"Mean arterial pressure {round_number(map_value, 1)} mmHg: +{map_points} points") # 5. 心率评分 if heart_rate >= 180: hr_points = 4 elif 140 <= heart_rate < 180: hr_points = 3 elif 110 <= heart_rate < 140: hr_points = 2 elif 70 <= heart_rate < 110: hr_points = 0 elif 55 <= heart_rate < 70: hr_points = 2 elif 40 <= heart_rate < 55: hr_points = 3 else: # < 40 hr_points = 4 score += hr_points explanation_parts.append(f"Heart rate {heart_rate} bpm: +{hr_points} points") # 6. 呼吸频率评分 if respiratory_rate >= 50: rr_points = 4 elif 35 <= respiratory_rate < 50: rr_points = 3 elif 25 <= respiratory_rate < 35: rr_points = 1 elif 12 <= respiratory_rate < 25: rr_points = 0 elif 10 <= respiratory_rate < 12: rr_points = 1 elif 6 <= respiratory_rate < 10: rr_points = 2 else: # < 6 rr_points = 4 score += rr_points explanation_parts.append(f"Respiratory rate {respiratory_rate} breaths/min: +{rr_points} points") # 7. 氧合评分 if fio2 >= 50: # 使用A-a梯度 if aa_gradient >= 500: oxy_points = 4 elif 350 <= aa_gradient < 500: oxy_points = 3 elif 200 <= aa_gradient < 350: oxy_points = 2 else: # < 200 oxy_points = 0 explanation_parts.append(f"A-a gradient {aa_gradient} mmHg (FiO2 {fio2}%): +{oxy_points} points") else: # 使用PaO2 if pao2 >= 70: oxy_points = 0 elif 61 <= pao2 < 70: oxy_points = 1 elif 55 <= pao2 < 61: oxy_points = 3 else: # < 55 oxy_points = 4 explanation_parts.append(f"PaO2 {pao2} mmHg (FiO2 {fio2}%): +{oxy_points} points") score += oxy_points # 8. pH评分 if ph >= 7.7: ph_points = 4 elif 7.6 <= ph < 7.7: ph_points = 3 elif 7.5 <= ph < 7.6: ph_points = 1 elif 7.33 <= ph < 7.5: ph_points = 0 elif 7.25 <= ph < 7.33: ph_points = 2 elif 7.15 <= ph < 7.25: ph_points = 3 else: # < 7.15 ph_points = 4 score += ph_points explanation_parts.append(f"Arterial pH {ph}: +{ph_points} points") # 9. 钠评分 if sodium >= 180: na_points = 4 elif 160 <= sodium < 180: na_points = 3 elif 155 <= sodium < 160: na_points = 2 elif 150 <= sodium < 155: na_points = 1 elif 130 <= sodium < 150: na_points = 0 elif 120 <= sodium < 130: na_points = 2 elif 111 <= sodium < 120: na_points = 3 else: # < 111 na_points = 4 score += na_points explanation_parts.append(f"Serum sodium {sodium} mmol/L: +{na_points} points") # 10. 钾评分 if potassium >= 7.0: k_points = 4 elif 6.0 <= potassium < 7.0: k_points = 3 elif 5.5 <= potassium < 6.0: k_points = 1 elif 3.5 <= potassium < 5.5: k_points = 0 elif 3.0 <= potassium < 3.5: k_points = 1 elif 2.5 <= potassium < 3.0: k_points = 2 else: # < 2.5 k_points = 4 score += k_points explanation_parts.append(f"Serum potassium {potassium} mmol/L: +{k_points} points") # 11. 肌酐评分 if creatinine >= 3.5 and acute_renal_failure: cr_points = 8 elif 2.0 <= creatinine < 3.5 and acute_renal_failure: cr_points = 6 elif creatinine >= 3.5 and chronic_renal_failure: cr_points = 4 elif 1.5 <= creatinine < 2.0 and acute_renal_failure: cr_points = 4 elif 2.0 <= creatinine < 3.5 and chronic_renal_failure: cr_points = 3 elif 1.5 <= creatinine < 2.0 and chronic_renal_failure: cr_points = 2 elif 0.6 <= creatinine < 1.5: cr_points = 0 else: # < 0.6 cr_points = 2 score += cr_points renal_status = "" if acute_renal_failure: renal_status = " (acute renal failure)" elif chronic_renal_failure: renal_status = " (chronic renal failure)" explanation_parts.append(f"Serum creatinine {creatinine} mg/dL{renal_status}: +{cr_points} points") # 12. 血细胞比容评分 if hematocrit >= 60: hct_points = 4 elif 50 <= hematocrit < 60: hct_points = 2 elif 46 <= hematocrit < 50: hct_points = 1 elif 30 <= hematocrit < 46: hct_points = 0 elif 20 <= hematocrit < 30: hct_points = 2 else: # < 20 hct_points = 4 score += hct_points explanation_parts.append(f"Hematocrit {hematocrit}%: +{hct_points} points") # 13. 白细胞计数评分 if wbc >= 40: wbc_points = 4 elif 20 <= wbc < 40: wbc_points = 2 elif 15 <= wbc < 20: wbc_points = 1 elif 3 <= wbc < 15: wbc_points = 0 elif 1 <= wbc < 3: wbc_points = 2 else: # < 1 wbc_points = 4 score += wbc_points explanation_parts.append(f"White blood cell count {wbc} ×10³/mm³: +{wbc_points} points") # 14. Glasgow昏迷评分 gcs_points = 15 - gcs score += gcs_points explanation_parts.append(f"Glasgow Coma Scale {gcs}: +{gcs_points} points (15 - GCS)") # 生成解释 explanation = "APACHE II Score calculation:\n\n" explanation += "\n".join([f"• {part}" for part in explanation_parts]) explanation += f"\n\nTotal APACHE II Score: {score} points" # 添加风险解释 if score < 10: risk_category = "Low risk" mortality_risk = "<10%" elif score < 15: risk_category = "Moderate risk" mortality_risk = "10-25%" elif score < 20: risk_category = "High risk" mortality_risk = "25-50%" elif score < 25: risk_category = "Very high risk" mortality_risk = "50-75%" else: risk_category = "Extremely high risk" mortality_risk = ">75%" explanation += f"\n\nRisk Category: {risk_category}" explanation += f"\nEstimated Hospital Mortality: {mortality_risk}" return CalculationResult( value=score, unit="points", explanation=explanation, metadata={ "age_points": age_points, "organ_failure_points": organ_points, "temperature_points": temp_points, "map_points": map_points, "heart_rate_points": hr_points, "respiratory_rate_points": rr_points, "oxygenation_points": oxy_points, "ph_points": ph_points, "sodium_points": na_points, "potassium_points": k_points, "creatinine_points": cr_points, "hematocrit_points": hct_points, "wbc_points": wbc_points, "gcs_points": gcs_points, "risk_category": risk_category, "mortality_risk": mortality_risk, "map_value": round_number(map_value, 1) } )

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/winninghealth/medcalcmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server