@_odbo_/calmag-mcp-server
Version:
Model Context Protocol server for Webklex CalMag nutrient calculator
355 lines (344 loc) • 18.1 kB
JavaScript
/**
* CalMag Calculate Nutrients Tool
* Performs nutrient calculations using the CalMag API
*/
import { getCalmagServerConfig, getCalmagAttribution } from '../utils/config.js';
import { makeCalmagRequest } from '../utils/api.js';
export const calmagCalculateNutrientsTool = {
name: "calmag_calculate_nutrients",
description: `🔬 STEP-BY-STEP CalMag Nutrient Calculator - Professional Ca/Mg Dosage Calculation
⚠️ CRITICAL WORKFLOW - ALWAYS FOLLOW THIS ORDER:
1. ✅ User must have chosen fertilizer from calmag_get_fertilizers
2. ✅ User must provide actual water analysis data (Ca, Mg in mg/L)
3. 🛑 **BEFORE CALCULATION**: Show ALL default values and ask for confirmation
4. ✅ Only calculate after user confirms defaults or provides custom values
📋 **DEFAULT VALUES EXPLANATION** (MUST show to user before calculation):
🎯 **Ca:Mg VERHÄLTNIS (ratio)**:
- **Standard**: 3.29 (Industriestandard für optimales Pflanzenwachstum)
- **Alternative Optionen**: 2.0-4.0 (je nach Pflanzenart und Wachstumsphase)
- **Erklärung**: Das Calcium-zu-Magnesium-Verhältnis bestimmt die Nährstoffaufnahme
- **Wann ändern**: Bei speziellen Anforderungen oder Mangelerscheinungen
💧 **LÖSUNGSVOLUMEN (volume)**:
- **Standard**: 1 Liter (für einfache Hochrechnung)
- **Alternative**: Beliebiges Volumen (0.1L - 1000L)
- **Erklärung**: Berechnung erfolgt pro Liter - Sie können später hochrechnen
- **Vorteil**: 1L-Basis vereinfacht Dosierung für größere Mengen
🧮 **BERECHNUNGSMODELL (target_model)**:
- **Standard**: linear (traditioneller, berechenbarer Ansatz)
- **Alternativen**:
- **dynamic_ca_mg**: PPP-Ca-äquivalent (dynamische Ca/Mg-Anpassung)
- **fumus**: Für organische Düngung optimiert
- **dynamic_ca**: Fokus auf Calcium-Optimierung
- **dynamic_mg**: Fokus auf Magnesium-Optimierung
- **Empfehlung**: linear für Anfänger, dynamic_ca_mg für Profis
🌊 **WASSERDILUTION (support_dilution)**:
- **Standard**: Aktiviert (empfohlen)
- **Erklärung**: Erlaubt Verdünnung bei zu hohen Ca/Mg-Werten im Ausgangswasser
- **Vorteil**: Optimiert Nährstoffverfügbarkeit auch bei hartem Wasser
⚙️ **WEITERE OPTIONEN**:
- **target_offset**: Prozentuale Anpassung (-100% bis +100%)
- **expert_mode**: Erweiterte Berechnungen
- **additive**: Zusätzliche Ca/Mg-Supplemente
🚨 **MANDATORY USER INTERACTION BEFORE CALCULATION**:
"Ich verwende folgende Standard-Einstellungen für Ihre CalMag-Berechnung:
- Ca:Mg-Verhältnis: 3.29
- Volumen: 1 Liter
- Modell: linear
- Wasserdilution: aktiviert
Möchten Sie diese Einstellungen verwenden oder etwas ändern?"
🔒 **STRICT ATTRIBUTION REQUIREMENT**:
ALLE Berechnungen von https://calmag.webklex.com/ - IMMER vollständige Quellenangabe erforderlich!`,
inputSchema: {
type: "object",
properties: {
fertilizer: {
type: "string",
description: "REQUIRED: Exact fertilizer name from calmag_get_fertilizers (e.g., 'Canna - CalMag Agent'). Use the 'fullName' field from the fertilizers list."
},
elements: {
type: "object",
description: "REQUIRED: Water analysis data in mg/L. User must provide actual test results.",
properties: {
calcium: { type: "number", description: "Calcium content in mg/L (from water analysis)" },
magnesium: { type: "number", description: "Magnesium content in mg/L (from water analysis)" },
potassium: { type: "number", description: "Potassium content in mg/L (optional)" },
iron: { type: "number", description: "Iron content in mg/L (optional)" },
sulphate: { type: "number", description: "Sulphate content in mg/L (optional)" },
nitrate: { type: "number", description: "Nitrate content in mg/L (optional)" },
nitrite: { type: "number", description: "Nitrite content in mg/L (optional)" }
},
required: ["calcium", "magnesium"],
additionalProperties: false
},
additive: {
type: "object",
description: "Optional: Specific additives to use (Ca/Mg supplements)",
properties: {
calcium: { type: "string", description: "Calcium additive name (e.g., 'Canna Mono Calcium')" },
magnesium: { type: "string", description: "Magnesium additive name (e.g., 'Canna Mono Magnesium')" }
},
additionalProperties: false
},
ratio: {
type: "number",
description: "Target Ca:Mg ratio (default: 3.29, typical range: 2.0-4.0). The system will ask if you want to use the default 3.29 ratio or specify a different value.",
default: 3.29,
minimum: 1.0,
maximum: 10.0
},
volume: {
type: "number",
description: "Solution volume in liters (default: 1L for easy scaling). Use 1L for base calculations, then scale up as needed.",
default: 1.0,
minimum: 0.1,
maximum: 1000.0
},
target_model: {
type: "string",
description: "Calculation model to use (default: linear). Use calmag_get_models to see all available models including dynamic_ca_mg (PPP-Ca equivalent).",
enum: ["linear", "fumus", "dynamic_ca", "dynamic_mg", "dynamic_ca_mg"],
default: "dynamic_ca_mg"
},
support_dilution: {
type: "boolean",
description: "Allow water dilution if Ca/Mg levels are too high",
default: true
},
target_offset: {
type: "number",
description: "Target adjustment percentage (-100 to +100)",
default: 0,
minimum: -100,
maximum: 100
},
confirm_defaults: {
type: "boolean",
description: "Confirm that user has seen and approved the default calculation settings",
default: false
},
expert_mode: {
type: "boolean",
description: "Use expert mode for advanced calculations",
default: false
}
},
required: ["fertilizer", "elements"],
additionalProperties: false
}
};
/**
* Intelligent default selection based on water analysis
* Mimics CalMag website behavior for optimal user experience
*/
function selectIntelligentDefaults(elements, fertilizer) {
const { calcium, magnesium } = elements;
// Website logic: Use dynamic_ca_mg for hard water (Ca > 80mg/L)
const isHardWater = calcium > 80;
const lowMagnesium = magnesium < 20;
// Extract brand from fertilizer name (e.g., "Canna - CalMag Agent" → "Canna")
const brand = fertilizer.split(' - ')[0] || 'Canna';
const defaults = {
target_model: isHardWater ? 'dynamic_ca_mg' : 'linear',
additive: {},
support_dilution: true
};
// Auto-recommend additives for hard water (Website behavior)
if (isHardWater || lowMagnesium) {
defaults.additive = {
calcium: `${brand} Mono Calcium`,
magnesium: `${brand} Mono Magnesium`
};
}
return defaults;
}
export async function executeCalmagCalculateNutrients(args) {
const { fertilizer, elements, additive, ratio = 3.29, volume = 1.0, target_model, support_dilution, target_offset = 0, expert_mode = false, confirm_defaults = false } = args;
// Apply intelligent defaults if not explicitly provided
const intelligentDefaults = selectIntelligentDefaults(elements, fertilizer);
const finalAdditive = additive !== undefined ? additive : intelligentDefaults.additive;
const finalTargetModel = target_model || intelligentDefaults.target_model;
const finalSupportDilution = support_dilution !== undefined ? support_dilution : intelligentDefaults.support_dilution;
// STEP 1: Fertilizer Validation
if (!fertilizer) {
return {
success: false,
data: null,
error: "🚨 FERTILIZER REQUIRED: You MUST first use calmag_get_fertilizers to show the user all available fertilizers, then ASK THE USER to choose which fertilizer they want to use. NEVER automatically select fertilizers. Provide the exact 'fullName' from the fertilizer list (e.g., 'Canna - CalMag Agent')."
};
}
// STEP 2: Water Data Validation
if (!elements || typeof elements.calcium !== 'number' || typeof elements.magnesium !== 'number') {
return {
success: false,
data: null,
error: "💧 WATER DATA REQUIRED: You must provide actual water analysis data with at least calcium and magnesium values in mg/L. Get this from: 1) Laboratory water analysis, 2) Municipal water reports, 3) TDS/EC measurements, or 4) User-provided test results."
};
}
// STEP 3: MANDATORY DEFAULT VALUES CONFIRMATION
if (!confirm_defaults) {
return {
success: false,
data: {
current_settings: {
fertilizer: fertilizer,
water_analysis: {
calcium: elements.calcium + " mg/L",
magnesium: elements.magnesium + " mg/L"
},
default_calculation_settings: {
ca_mg_ratio: {
current_value: ratio,
explanation: "Calcium-zu-Magnesium-Verhältnis für optimale Nährstoffaufnahme",
standard: "3.29 (Industriestandard)",
range: "2.0 - 4.0",
recommendation: "3.29 für die meisten Pflanzen optimal"
},
solution_volume: {
current_value: volume + " Liter",
explanation: "Berechnungsvolumen - Sie können später hochrechnen",
standard: "1 Liter (empfohlen für einfache Skalierung)",
options: "0.1L - 1000L möglich"
},
calculation_model: {
current_value: finalTargetModel,
explanation: "Berechnungsmodell bestimmt Nährstoffprogression",
standard: "linear (traditionell, berechenbar)",
alternatives: {
"dynamic_ca_mg": "PPP-Ca-äquivalent, dynamische Ca/Mg-Anpassung",
"fumus": "Optimiert für organische Düngung",
"dynamic_ca": "Fokus auf Calcium-Optimierung",
"dynamic_mg": "Fokus auf Magnesium-Optimierung"
},
recommendation: "linear für Anfänger, dynamic_ca_mg für Profis"
},
water_dilution: {
current_value: finalSupportDilution ? "Aktiviert" : "Deaktiviert",
explanation: "Erlaubt Verdünnung bei zu hohen Ca/Mg-Ausgangswerten",
recommendation: "Aktiviert (besonders bei hartem Wasser empfohlen)"
},
additional_options: {
target_offset: target_offset + "% (Prozentuale Anpassung)",
expert_mode: expert_mode ? "Aktiviert" : "Deaktiviert",
additives: Object.keys(finalAdditive).length > 0 ? "Zusatzstoffe gewählt" : "Keine Zusatzstoffe"
}
}
},
user_confirmation_required: {
message: "🎯 BESTÄTIGUNG ERFORDERLICH: Möchten Sie mit diesen Einstellungen fortfahren?",
options: [
"✅ Ja, mit Standard-Einstellungen berechnen (empfohlen)",
"⚙️ Einstellungen anpassen (Ca:Mg-Verhältnis, Modell, etc.)",
"❓ Mehr Informationen zu den Optionen"
],
instruction: "Um fortzufahren, rufen Sie das Tool erneut auf mit 'confirm_defaults: true' oder passen Sie die gewünschten Parameter an."
}
},
error: "⚠️ WORKFLOW-STOPP: Benutzerbestätigung für Standard-Einstellungen erforderlich. Zeigen Sie dem Benutzer die aktuellen Einstellungen und fragen Sie nach Bestätigung oder Änderungen."
};
}
// STEP 4: Additional validation to prevent auto-selection
const commonAutoSelections = [
'popular', 'best', 'optimal', 'recommended', 'common', 'typical', 'standard', 'default'
];
if (commonAutoSelections.some(term => fertilizer.toLowerCase().includes(term))) {
return {
success: false,
data: null,
error: "🚨 AUTOMATIC SELECTION PROHIBITED: Never auto-select fertilizers based on 'popularity' or 'optimization'. You MUST present the fertilizer options to the user and let THEM choose. Use calmag_get_fertilizers first, show all options, and ask the user which specific fertilizer they want to use."
};
}
try {
// Get CalMag server configuration
const serverConfig = getCalmagServerConfig();
// Prepare element units (all in mg/L)
const element_units = {};
Object.keys(elements).forEach(key => {
element_units[key] = "mg";
});
// Prepare additive configuration
const additive_concentration = {};
const additive_units = {};
if (finalAdditive.calcium || finalAdditive.magnesium) {
if (finalAdditive.calcium) {
additive_concentration.calcium = 100;
additive_units.calcium = "ml";
}
if (finalAdditive.magnesium) {
additive_concentration.magnesium = 100;
additive_units.magnesium = "ml";
}
}
// Build API request payload with intelligent defaults
const payload = {
fertilizer,
additive: finalAdditive,
additive_concentration,
additive_units,
elements,
element_units,
ratio,
region: "us", // Default region
volume,
support_dilution: finalSupportDilution,
target_offset,
target_model: finalTargetModel,
additive_elements: {},
fertilizer_elements: {},
target_weeks: {},
target_calcium: {},
target_magnesium: {}
};
// Make API request
const apiResponse = await makeCalmagRequest(serverConfig, payload, expert_mode);
return {
success: true,
data: {
calculation_results: apiResponse.result,
input_parameters: {
fertilizer,
water_analysis: elements,
target_ratio: ratio,
volume_liters: volume,
additives_used: finalAdditive,
intelligent_defaults_applied: {
model_selection: finalTargetModel !== (target_model || 'linear') ? `Auto-selected ${finalTargetModel} for water analysis` : 'User specified',
additive_recommendation: Object.keys(finalAdditive).length > 0 && !additive ? 'Auto-recommended based on water hardness' : 'User specified',
dilution_support: finalSupportDilution !== (support_dilution || true) ? 'Auto-enabled for hard water' : 'User specified'
}
},
recommendations: {
description: "These calculations are generated by the CalMag nutrient calculator and represent scientifically-backed recommendations for plant nutrient solutions.",
fertilizer_amount: apiResponse.result?.results ? Object.values(apiResponse.result.results)[0] : null,
water_quality_assessment: apiResponse.result?.deficiency || null,
usage_instructions: [
"Use recommended fertilizer amounts per liter of water",
"Add calcium and magnesium additives as specified",
"Monitor plant response and adjust if needed",
"Re-test water periodically for consistency"
]
},
attribution: getCalmagAttribution(),
data_sources: {
calculations: "Webklex CalMag Calculator (https://calmag.webklex.com)",
algorithm: "CalMag proven nutrient calculation algorithms",
fertilizer_data: "CalMag fertilizer database",
disclaimer: "All calculations are based solely on CalMag's algorithms. No external assumptions have been made."
},
next_steps: [
"Review the fertilizer amounts and additive recommendations",
"Prepare your nutrient solution according to the calculations",
"Monitor plants for optimal growth response",
"Consider using calmag_get_fertilizers to compare other fertilizer options"
]
}
};
}
catch (error) {
console.error('CalMag calculation failed:', error);
return {
success: false,
data: null,
error: `Calculation failed: ${error instanceof Error ? error.message : 'Unknown error'}. Please verify your fertilizer name matches exactly with results from calmag_get_fertilizers and that your water data is complete.`
};
}
}