UNPKG

@_odbo_/calmag-mcp-server

Version:

Model Context Protocol server for Webklex CalMag nutrient calculator

144 lines (138 loc) • 6.03 kB
/** * CalMag Get Fertilizers Tool * Fetches available fertilizers from the CalMag API */ import { getCalmagAttribution } from '../utils/config.js'; import { fetchFertilizersFromApi } from '../utils/api.js'; export const calmagGetFertilizersTool = { name: "calmag_get_fertilizers", description: `Get all available fertilizers from the CalMag professional nutrient database. 🌱 **FERTILIZER DATABASE:** - **15+ Professional Brands**: Canna, BioBizz, General Hydroponics, Advanced Nutrients, and more - **Complete Product Lines**: Base nutrients, Cal-Mag products, specialized formulations - **Detailed Compositions**: Exact nutrient profiles, densities, pH values for each product šŸ“‹ **WHEN TO USE:** - **ALWAYS use this tool FIRST** before making any nutrient calculations - To see all available fertilizer options for your plant nutrition system - To compare different brands and products - To get exact fertilizer names for use in calmag_calculate_nutrients āš ļø **CRITICAL WORKFLOW REQUIREMENT:** 1. **MANDATORY FIRST STEP**: Call this tool to show fertilizer options 2. **PRESENT ALL OPTIONS**: Show the complete list to the user 3. **ASK USER TO CHOOSE**: Never automatically select fertilizers 4. **USE EXACT NAMES**: Copy the 'fullName' field exactly for calculations šŸ”’ **STRICT USAGE POLICY:** - NEVER automatically select 'popular' or 'optimal' fertilizers - ALWAYS let the user choose their preferred product - NEVER make assumptions about user preferences - ALWAYS use exact fertilizer names from this database šŸ’” **INTEGRATION:** Use the exact 'fullName' from results (e.g., 'Canna - CalMag Agent') as the 'fertilizer' parameter in calmag_calculate_nutrients for plant nutrition calculations.`, inputSchema: { type: "object", properties: { brand: { type: "string", description: "Optional: Filter fertilizers by brand name (e.g., 'Canna', 'BioBizz')" }, includeElements: { type: "boolean", description: "Include detailed element compositions in the response", default: true } }, additionalProperties: false } }; export async function executeCalmagGetFertilizers(args) { const { brand, includeElements = true } = args; try { // Fetch data from the new API endpoint const apiResponse = await fetchFertilizersFromApi(); // Transform the API response to match our expected format const transformedData = transformApiResponseToToolFormat(apiResponse, brand, includeElements); return { success: true, data: { ...transformedData, query: { brand: brand || "all", includeElements, resultsCount: transformedData.totalCount }, usage: { description: "Use the fertilizer name (e.g., 'Canna - CalMag Agent') when making nutrient calculations", example_usage: { fertilizer_name: transformedData.fertilizers[0]?.fullName || "Canna - CalMag Agent", curl_example: `curl -X POST -H "Content-Type: application/json" -d '{"fertilizer":"${transformedData.fertilizers[0]?.fullName || "Canna - CalMag Agent"}","elements":{"calcium":0,"magnesium":0},"ratio":3.5}' https://www.calmag.eu/` } }, attribution: getCalmagAttribution(), data_sources: { fertilizer_database: "CalMag API fertilizer database", website: "https://www.calmag.eu/", api_endpoint: "https://www.calmag.eu/?method=fertilizers", total_brands: transformedData.brands.length, total_products: transformedData.totalCount, api_version: apiResponse.version } } }; } catch (error) { console.error('Error fetching fertilizers:', error); return { success: false, data: null, error: `Failed to fetch fertilizers from API: ${error instanceof Error ? error.message : 'Unknown error'}` }; } } /** * Transforms the API response into the format expected by the tool */ function transformApiResponseToToolFormat(apiResponse, brandFilter, includeElements = true) { // Extract unique brands from fertilizers const brandMap = new Map(); const fertilizers = []; // Process fertilizers from API response Object.entries(apiResponse.fertilizers).forEach(([fullName, data]) => { const brandName = data.brand; const productName = data.name; // Skip if brand filter is provided and doesn't match if (brandFilter && !brandName.toLowerCase().includes(brandFilter.toLowerCase())) { return; } // Add to fertilizers array const fertilizerItem = { key: productName.toLowerCase().replace(/\s+/g, '_'), name: productName, brandName, fullName, elements: includeElements ? data.elements : undefined, density: data.density, ph: data.ph }; fertilizers.push(fertilizerItem); // Process brand data if (!brandMap.has(brandName)) { brandMap.set(brandName, { key: brandName.toLowerCase().replace(/\s+/g, '_'), name: brandName, website: data.link || { de: '', us: '' }, products: [] }); } // Add product to brand const brandData = brandMap.get(brandName); brandData.products.push(fertilizerItem); }); // Convert brands map to array const brands = Array.from(brandMap.values()); return { brands, fertilizers, totalCount: fertilizers.length, version: apiResponse.version }; }