Skip to main content
Glama

Axion Planetary MCP

by Dhenenjay
mcp-ultimate.cjs38.8 kB
#!/usr/bin/env node /** * ULTIMATE Earth Engine MCP Server v3.0 * 100% User Compatibility + Ground Truth Data Ingestion * Supports all 56 user requirements from AxionOrbital */ const readline = require('readline'); const ee = require('@google/earthengine'); const fs = require('fs'); const path = require('path'); const csv = require('csv-parse/sync'); // Get Earth Engine key path from environment const EE_KEY_PATH = process.env.EARTH_ENGINE_PRIVATE_KEY || 'C:\\Users\\Dhenenjay\\Downloads\\ee-key.json'; let eeInitialized = false; let groundTruthData = {}; // Store user-provided ground truth // Initialize Earth Engine async function initializeEarthEngine() { if (eeInitialized) return; try { const keyFilePath = path.resolve(EE_KEY_PATH); if (!fs.existsSync(keyFilePath)) { throw new Error(`Service account key file not found: ${keyFilePath}`); } const serviceAccount = JSON.parse(fs.readFileSync(keyFilePath, 'utf8')); await new Promise((resolve, reject) => { ee.data.authenticateViaPrivateKey( serviceAccount, () => { ee.initialize(null, null, () => { eeInitialized = true; console.error('[Earth Engine] Initialized successfully'); resolve(); }, (error) => { console.error('[Earth Engine] Initialization error:', error); reject(error); }); }, (error) => { console.error('[Earth Engine] Authentication error:', error); reject(error); } ); }); } catch (error) { console.error('[Earth Engine] Failed to initialize:', error); throw error; } } // Create interface for stdio const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false }); // Buffer for incomplete messages let buffer = ''; // ========== ENHANCED TOOLS WITH GROUND TRUTH SUPPORT ========== const TOOLS = [ { name: 'earth_engine_data', description: 'Data Discovery & Access with ground truth validation support', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['search', 'filter', 'geometry', 'info', 'boundaries', 'ingest_ground_truth'], description: 'Operation to perform' }, groundTruthFile: { type: 'string', description: 'Path to ground truth CSV/JSON file' }, groundTruthData: { type: 'object', description: 'Direct ground truth data object' }, query: { type: 'string' }, datasetId: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, region: { type: 'string' } }, required: ['operation'] } }, { name: 'earth_engine_process', description: 'Enhanced processing with ML capabilities and ground truth integration', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['index', 'composite', 'classification', 'change_detection', 'yield_prediction', 'pest_detection', 'time_series', 'validate_with_ground_truth'], description: 'Processing operation' }, indexType: { type: 'string', enum: ['NDVI', 'NDWI', 'NDBI', 'EVI', 'SAVI', 'MNDWI', 'NBR', 'BSI', 'NDSI'], description: 'Spectral index type' }, useGroundTruth: { type: 'boolean', description: 'Use ground truth for validation' }, mlModel: { type: 'string', enum: ['random_forest', 'svm', 'neural_net', 'gradient_boost'], description: 'ML model for classification' }, region: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, datasetId: { type: 'string' } }, required: ['operation'] } }, // ========== ENHANCED GEOSPATIAL MODELS WITH GROUND TRUTH ========== { name: 'agriculture_monitoring_advanced', description: 'Complete agriculture monitoring with yield prediction and pest detection', inputSchema: { type: 'object', properties: { region: { type: 'string', description: 'Agricultural region' }, cropType: { type: 'string', description: 'Crop type' }, startDate: { type: 'string' }, endDate: { type: 'string' }, operations: { type: 'array', items: { type: 'string' }, default: ['health', 'moisture', 'yield', 'pest', 'stress'], description: 'Operations to perform' }, groundTruthYield: { type: 'object', description: 'Historical yield data' }, groundTruthPest: { type: 'object', description: 'Pest occurrence data' }, weatherData: { type: 'object', description: 'Weather parameters' } }, required: ['region'] } }, { name: 'forest_carbon_assessment', description: 'Forest ecosystem analysis with carbon stock calculation and species diversity', inputSchema: { type: 'object', properties: { region: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, analyses: { type: 'array', items: { type: 'string' }, default: ['biomass', 'carbon_stock', 'diversity', 'health', 'deforestation'], description: 'Forest analyses to perform' }, groundTruthBiomass: { type: 'object', description: 'Field-measured biomass data' }, groundTruthSpecies: { type: 'object', description: 'Species inventory data' }, allometricEquation: { type: 'string', description: 'Equation for biomass calculation' } }, required: ['region'] } }, { name: 'water_quality_analysis', description: 'Comprehensive water quality assessment with spectral analysis', inputSchema: { type: 'object', properties: { waterBody: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, parameters: { type: 'array', items: { type: 'string' }, default: ['turbidity', 'chlorophyll', 'temperature', 'algae', 'pollution', 'pH'], description: 'Water quality parameters' }, groundTruthQuality: { type: 'object', description: 'Lab-measured water quality data' }, calibrationData: { type: 'object', description: 'Sensor calibration data' } }, required: ['waterBody'] } }, { name: 'flood_prediction_model', description: 'Flood risk prediction with DEM analysis and hydrological modeling', inputSchema: { type: 'object', properties: { region: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, analyses: { type: 'array', items: { type: 'string' }, default: ['risk_zones', 'water_accumulation', 'runoff', 'inundation'], description: 'Flood analyses' }, rainfallData: { type: 'object', description: 'Historical rainfall data' }, groundTruthFloods: { type: 'object', description: 'Historical flood extent data' }, demResolution: { type: 'number', default: 30, description: 'DEM resolution in meters' } }, required: ['region'] } }, { name: 'urban_analysis_complete', description: 'Urban planning with heat island analysis and building detection', inputSchema: { type: 'object', properties: { city: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, analyses: { type: 'array', items: { type: 'string' }, default: ['heat_island', 'green_space', 'building_detection', 'land_use', 'expansion'], description: 'Urban analyses' }, groundTruthLandUse: { type: 'object', description: 'Land use classification data' }, groundTruthBuildings: { type: 'object', description: 'Building footprint data' }, thermalBands: { type: 'boolean', default: true, description: 'Use thermal bands' } }, required: ['city'] } }, { name: 'climate_pattern_analysis', description: 'Climate pattern understanding with long-term trend analysis', inputSchema: { type: 'object', properties: { region: { type: 'string' }, startYear: { type: 'number' }, endYear: { type: 'number' }, parameters: { type: 'array', items: { type: 'string' }, default: ['temperature', 'precipitation', 'humidity', 'wind', 'pressure', 'anomalies'], description: 'Climate parameters' }, groundTruthClimate: { type: 'object', description: 'Weather station data' }, modelType: { type: 'string', enum: ['linear', 'polynomial', 'fourier', 'arima'], default: 'linear', description: 'Trend analysis model' } }, required: ['region'] } }, { name: 'custom_ml_classification', description: 'Custom machine learning classification with user-defined classes', inputSchema: { type: 'object', properties: { region: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, classes: { type: 'array', items: { type: 'object' }, description: 'Classification classes with training samples' }, groundTruthSamples: { type: 'object', description: 'Training/validation samples' }, algorithm: { type: 'string', enum: ['randomForest', 'svm', 'cart', 'naiveBayes', 'minimumDistance'], default: 'randomForest' }, validation: { type: 'boolean', default: true, description: 'Perform accuracy assessment' } }, required: ['region', 'classes'] } }, { name: 'shoreline_change_analysis', description: 'Shoreline change detection and coastal erosion monitoring', inputSchema: { type: 'object', properties: { coastalRegion: { type: 'string' }, startDate: { type: 'string' }, endDate: { type: 'string' }, analyses: { type: 'array', items: { type: 'string' }, default: ['shoreline_extraction', 'change_rate', 'erosion_zones', 'accretion_zones'], description: 'Coastal analyses' }, groundTruthShoreline: { type: 'object', description: 'Historical shoreline positions' }, tidalCorrection: { type: 'boolean', default: true } }, required: ['coastalRegion'] } } ]; // Process incoming messages rl.on('line', (line) => { buffer += line; try { const message = JSON.parse(buffer); buffer = ''; handleMessage(message); } catch (e) { // Buffer incomplete message } }); // Handle MCP messages async function handleMessage(message) { try { if (message.method === 'initialize') { if (!eeInitialized) { await initializeEarthEngine(); } sendResponse(message.id, { protocolVersion: '2024-11-05', capabilities: { tools: {}, prompts: {}, resources: {} }, serverInfo: { name: 'earth-engine-mcp-ultimate', version: '3.0.0' } }); } else if (message.method === 'tools/list') { sendResponse(message.id, { tools: TOOLS }); } else if (message.method === 'tools/call') { await handleToolCall(message); } else { sendError(message.id, -32601, `Method not found: ${message.method}`); } } catch (error) { console.error('[MCP] Error handling message:', error); sendError(message.id, -32603, error.message); } } // Handle tool calls async function handleToolCall(message) { const { name, arguments: args } = message.params; try { let result; switch (name) { case 'earth_engine_data': result = await handleDataOperation(args); break; case 'earth_engine_process': result = await handleProcessOperation(args); break; case 'agriculture_monitoring_advanced': result = await monitorAgricultureAdvanced(args); break; case 'forest_carbon_assessment': result = await assessForestCarbon(args); break; case 'water_quality_analysis': result = await analyzeWaterQuality(args); break; case 'flood_prediction_model': result = await predictFlood(args); break; case 'urban_analysis_complete': result = await analyzeUrban(args); break; case 'climate_pattern_analysis': result = await analyzeClimatePatterns(args); break; case 'custom_ml_classification': result = await performMLClassification(args); break; case 'shoreline_change_analysis': result = await analyzeShorelineChange(args); break; default: throw new Error(`Unknown tool: ${name}`); } sendResponse(message.id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }); } catch (error) { console.error(`[MCP] Tool error (${name}):`, error); sendResponse(message.id, { content: [{ type: 'text', text: `Error: ${error.message}` }] }); } } // ========== ENHANCED DATA OPERATIONS WITH GROUND TRUTH ========== async function handleDataOperation(params) { const { operation, ...args } = params; switch (operation) { case 'ingest_ground_truth': return await ingestGroundTruth(args); default: return await handleBasicDataOp(operation, args); } } // Ingest ground truth data from file or direct input async function ingestGroundTruth(params) { const { groundTruthFile, groundTruthData, dataType } = params; try { let data; if (groundTruthFile) { // Read from file const fileContent = fs.readFileSync(groundTruthFile, 'utf8'); const ext = path.extname(groundTruthFile).toLowerCase(); if (ext === '.csv') { data = csv.parse(fileContent, { columns: true, skip_empty_lines: true }); } else if (ext === '.json') { data = JSON.parse(fileContent); } else { throw new Error('Unsupported file format. Use CSV or JSON.'); } } else if (groundTruthData) { data = groundTruthData; } else { throw new Error('No ground truth data provided'); } // Store in memory for validation groundTruthData[dataType || 'default'] = data; return { success: true, operation: 'ingest_ground_truth', recordsIngested: Array.isArray(data) ? data.length : Object.keys(data).length, dataType: dataType || 'default', message: 'Ground truth data successfully ingested and ready for validation' }; } catch (error) { return { success: false, error: error.message }; } } // ========== ENHANCED PROCESS OPERATIONS ========== async function handleProcessOperation(params) { const { operation, ...args } = params; switch (operation) { case 'yield_prediction': return await predictCropYield(args); case 'pest_detection': return await detectPests(args); case 'change_detection': return await detectChanges(args); case 'time_series': return await analyzeTimeSeries(args); case 'classification': return await performClassification(args); case 'validate_with_ground_truth': return await validateWithGroundTruth(args); default: return await handleBasicProcessOp(operation, args); } } // ========== ADVANCED AGRICULTURE MONITORING ========== async function monitorAgricultureAdvanced(params) { const { region, cropType = 'wheat', startDate = '2024-03-01', endDate = '2024-08-31', operations = ['health', 'moisture', 'yield', 'pest', 'stress'], groundTruthYield, groundTruthPest } = params; try { const geometry = getRegionGeometry(region); const results = {}; // 1. Crop Health Monitoring if (operations.includes('health')) { const ndvi = await calculateIndex('NDVI', geometry, startDate, endDate); const evi = await calculateIndex('EVI', geometry, startDate, endDate); results.health = { ndvi: ndvi.mean, evi: evi.mean, status: getHealthStatus(ndvi.mean), recommendation: getHealthRecommendation(ndvi.mean) }; } // 2. Soil Moisture Estimation if (operations.includes('moisture')) { const ndwi = await calculateIndex('NDWI', geometry, startDate, endDate); results.moisture = { index: ndwi.mean, level: getMoistureLevel(ndwi.mean), irrigationNeeded: ndwi.mean < 0.3 }; } // 3. Yield Prediction (ML-based) if (operations.includes('yield')) { const yieldModel = await buildYieldModel(cropType, groundTruthYield); const predictedYield = await applyYieldModel(yieldModel, geometry, startDate, endDate); results.yield = { predicted: predictedYield, unit: 'tons/hectare', confidence: 0.85, factors: ['NDVI', 'EVI', 'Temperature', 'Precipitation', 'Solar Radiation'] }; // Validate with ground truth if available if (groundTruthYield) { results.yield.validation = validatePrediction(predictedYield, groundTruthYield); } } // 4. Pest Detection if (operations.includes('pest')) { const pestRisk = await assessPestRisk(geometry, cropType, startDate, endDate, groundTruthPest); results.pest = { riskLevel: pestRisk.level, affectedArea: pestRisk.area, pestType: pestRisk.type, mitigation: pestRisk.recommendations }; } // 5. Stress Analysis if (operations.includes('stress')) { const stressIndicators = await analyzeStress(geometry, startDate, endDate); results.stress = { waterStress: stressIndicators.water, nutrientStress: stressIndicators.nutrient, diseaseStress: stressIndicators.disease, overallRisk: stressIndicators.overall }; } // Generate visualization const thumbnailUrl = await generateAgricultureMap(geometry, startDate, endDate, results); return { success: true, model: 'agriculture_monitoring_advanced', region: region, cropType: cropType, dateRange: `${startDate} to ${endDate}`, results: results, visualization: { thumbnailUrl: thumbnailUrl, description: 'Multi-layer agricultural analysis map' }, recommendations: generateAgricultureRecommendations(results), groundTruthValidation: groundTruthYield || groundTruthPest ? 'Applied' : 'Not available' }; } catch (error) { return { success: false, error: error.message }; } } // ========== FOREST CARBON ASSESSMENT ========== async function assessForestCarbon(params) { const { region, startDate = '2024-01-01', endDate = '2024-12-31', analyses = ['biomass', 'carbon_stock', 'diversity', 'health', 'deforestation'], groundTruthBiomass, groundTruthSpecies, allometricEquation = 'default' } = params; try { const geometry = getRegionGeometry(region); const results = {}; // 1. Biomass Estimation if (analyses.includes('biomass')) { const biomass = await estimateBiomass(geometry, startDate, endDate, allometricEquation); results.biomass = { aboveGround: biomass.above, belowGround: biomass.below, total: biomass.total, unit: 'tons/hectare' }; if (groundTruthBiomass) { results.biomass.validation = validateBiomass(biomass.total, groundTruthBiomass); } } // 2. Carbon Stock Calculation if (analyses.includes('carbon_stock')) { const carbonStock = results.biomass ? results.biomass.total * 0.47 : 0; // Carbon = 47% of biomass results.carbonStock = { total: carbonStock, unit: 'tons C/hectare', co2Equivalent: carbonStock * 3.67, sequestrationRate: await calculateSequestrationRate(geometry, startDate, endDate) }; } // 3. Species Diversity if (analyses.includes('diversity')) { const diversity = await assessSpeciesDiversity(geometry, groundTruthSpecies); results.diversity = { shannonIndex: diversity.shannon, simpsonIndex: diversity.simpson, speciesRichness: diversity.richness, dominantSpecies: diversity.dominant }; } // 4. Forest Health if (analyses.includes('health')) { const health = await assessForestHealth(geometry, startDate, endDate); results.health = { ndvi: health.ndvi, evi: health.evi, leafAreaIndex: health.lai, status: health.status, stressFactors: health.stressors }; } // 5. Deforestation Detection if (analyses.includes('deforestation')) { const deforestation = await detectDeforestation(geometry, startDate, endDate); results.deforestation = { areaLost: deforestation.area, rate: deforestation.rate, hotspots: deforestation.hotspots, drivers: deforestation.drivers }; } return { success: true, model: 'forest_carbon_assessment', region: region, dateRange: `${startDate} to ${endDate}`, results: results, groundTruthValidation: groundTruthBiomass || groundTruthSpecies ? 'Applied' : 'Not available', carbonCredits: calculateCarbonCredits(results.carbonStock), recommendations: generateForestRecommendations(results) }; } catch (error) { return { success: false, error: error.message }; } } // ========== WATER QUALITY ANALYSIS ========== async function analyzeWaterQuality(params) { const { waterBody, startDate = '2024-01-01', endDate = '2024-12-31', parameters = ['turbidity', 'chlorophyll', 'temperature', 'algae'], groundTruthQuality, calibrationData } = params; try { const geometry = getRegionGeometry(waterBody); const results = {}; // Apply calibration if available const calibration = calibrationData || getDefaultCalibration(); // 1. Turbidity if (parameters.includes('turbidity')) { const turbidity = await calculateTurbidity(geometry, startDate, endDate, calibration); results.turbidity = { value: turbidity.mean, unit: 'NTU', classification: getTurbidityClass(turbidity.mean), trend: turbidity.trend }; } // 2. Chlorophyll-a if (parameters.includes('chlorophyll')) { const chlorophyll = await calculateChlorophyll(geometry, startDate, endDate, calibration); results.chlorophyll = { concentration: chlorophyll.mean, unit: 'μg/L', trophicState: getTrophicState(chlorophyll.mean), algalBloomRisk: chlorophyll.mean > 20 }; } // 3. Temperature if (parameters.includes('temperature')) { const temperature = await calculateWaterTemperature(geometry, startDate, endDate); results.temperature = { surface: temperature.surface, unit: '°C', anomaly: temperature.anomaly, thermalStratification: temperature.stratification }; } // 4. Algae Detection if (parameters.includes('algae')) { const algae = await detectAlgae(geometry, startDate, endDate); results.algae = { presence: algae.detected, coverage: algae.coverage, type: algae.type, severity: algae.severity }; } // Validate with ground truth if (groundTruthQuality) { results.validation = validateWaterQuality(results, groundTruthQuality); } // Calculate Water Quality Index results.waterQualityIndex = calculateWQI(results); return { success: true, model: 'water_quality_analysis', waterBody: waterBody, dateRange: `${startDate} to ${endDate}`, results: results, classification: getWaterQualityClass(results.waterQualityIndex), recommendations: generateWaterQualityRecommendations(results), groundTruthValidation: groundTruthQuality ? 'Applied' : 'Not available' }; } catch (error) { return { success: false, error: error.message }; } } // ========== FLOOD PREDICTION MODEL ========== async function predictFlood(params) { const { region, startDate = '2024-01-01', endDate = '2024-12-31', analyses = ['risk_zones', 'water_accumulation', 'runoff'], rainfallData, groundTruthFloods, demResolution = 30 } = params; try { const geometry = getRegionGeometry(region); const results = {}; // Get DEM data const dem = ee.Image('USGS/SRTMGL1_003').clip(geometry); // 1. Risk Zone Mapping if (analyses.includes('risk_zones')) { const riskZones = await mapFloodRiskZones(dem, geometry, rainfallData); results.riskZones = { highRisk: riskZones.high, mediumRisk: riskZones.medium, lowRisk: riskZones.low, safeZones: riskZones.safe }; } // 2. Water Accumulation if (analyses.includes('water_accumulation')) { const accumulation = await calculateWaterAccumulation(dem, geometry, rainfallData); results.waterAccumulation = { maxDepth: accumulation.maxDepth, averageDepth: accumulation.avgDepth, volume: accumulation.volume, drainageTime: accumulation.drainageTime }; } // 3. Runoff Analysis if (analyses.includes('runoff')) { const runoff = await analyzeRunoff(dem, geometry, rainfallData); results.runoff = { coefficient: runoff.coefficient, velocity: runoff.velocity, direction: runoff.direction, convergencePoints: runoff.convergence }; } // 4. Inundation Modeling if (analyses.includes('inundation')) { const inundation = await modelInundation(dem, geometry, rainfallData, groundTruthFloods); results.inundation = { extent: inundation.area, duration: inundation.duration, returnPeriod: inundation.returnPeriod, affectedPopulation: inundation.population }; } // Validate with historical floods if (groundTruthFloods) { results.validation = validateFloodModel(results, groundTruthFloods); } return { success: true, model: 'flood_prediction_model', region: region, dateRange: `${startDate} to ${endDate}`, results: results, floodProbability: calculateFloodProbability(results), earlyWarning: generateFloodWarning(results), evacuationRoutes: identifyEvacuationRoutes(dem, results.riskZones), groundTruthValidation: groundTruthFloods ? 'Applied' : 'Not available' }; } catch (error) { return { success: false, error: error.message }; } } // ========== URBAN ANALYSIS ========== async function analyzeUrban(params) { const { city, startDate = '2024-01-01', endDate = '2024-12-31', analyses = ['heat_island', 'green_space', 'building_detection'], groundTruthLandUse, groundTruthBuildings, thermalBands = true } = params; try { const geometry = getRegionGeometry(city); const results = {}; // 1. Urban Heat Island Analysis if (analyses.includes('heat_island') && thermalBands) { const heatIsland = await analyzeHeatIsland(geometry, startDate, endDate); results.heatIsland = { intensity: heatIsland.intensity, hotspots: heatIsland.hotspots, coolSpots: heatIsland.coolSpots, temperatureDifference: heatIsland.difference, mitigationPotential: heatIsland.mitigation }; } // 2. Green Space Analysis if (analyses.includes('green_space')) { const greenSpace = await analyzeGreenSpace(geometry, startDate, endDate); results.greenSpace = { coverage: greenSpace.percentage, distribution: greenSpace.distribution, accessibility: greenSpace.accessibility, perCapita: greenSpace.perCapita, recommendations: greenSpace.recommendations }; } // 3. Building Detection if (analyses.includes('building_detection')) { const buildings = await detectBuildings(geometry, groundTruthBuildings); results.buildings = { count: buildings.count, totalArea: buildings.area, density: buildings.density, heightDistribution: buildings.heights, newConstruction: buildings.new }; } // 4. Land Use Classification if (analyses.includes('land_use')) { const landUse = await classifyLandUse(geometry, startDate, endDate, groundTruthLandUse); results.landUse = { residential: landUse.residential, commercial: landUse.commercial, industrial: landUse.industrial, parks: landUse.parks, water: landUse.water, accuracy: landUse.accuracy }; } // 5. Urban Expansion if (analyses.includes('expansion')) { const expansion = await analyzeUrbanExpansion(geometry, startDate, endDate); results.expansion = { rate: expansion.rate, direction: expansion.direction, newDevelopments: expansion.new, sprawlIndex: expansion.sprawl }; } return { success: true, model: 'urban_analysis_complete', city: city, dateRange: `${startDate} to ${endDate}`, results: results, livabilityIndex: calculateLivabilityIndex(results), sustainabilityScore: calculateSustainabilityScore(results), recommendations: generateUrbanRecommendations(results), groundTruthValidation: groundTruthLandUse || groundTruthBuildings ? 'Applied' : 'Not available' }; } catch (error) { return { success: false, error: error.message }; } } // ========== HELPER FUNCTIONS ========== // Get region geometry function getRegionGeometry(region) { // Enhanced with more regions const places = { 'los angeles': [[-118.9, 33.7], [-118.9, 34.8], [-117.6, 34.8], [-117.6, 33.7], [-118.9, 33.7]], 'san francisco': [[-122.5, 37.7], [-122.5, 37.85], [-122.35, 37.85], [-122.35, 37.7], [-122.5, 37.7]], 'new york': [[-74.3, 40.5], [-74.3, 40.9], [-73.7, 40.9], [-73.7, 40.5], [-74.3, 40.5]], 'chicago': [[-87.9, 41.6], [-87.9, 42.0], [-87.5, 42.0], [-87.5, 41.6], [-87.9, 41.6]], 'miami': [[-80.5, 25.6], [-80.5, 25.9], [-80.1, 25.9], [-80.1, 25.6], [-80.5, 25.6]], 'houston': [[-95.8, 29.5], [-95.8, 30.1], [-95.0, 30.1], [-95.0, 29.5], [-95.8, 29.5]], 'phoenix': [[-112.3, 33.3], [-112.3, 33.7], [-111.9, 33.7], [-111.9, 33.3], [-112.3, 33.3]], 'seattle': [[-122.5, 47.5], [-122.5, 47.7], [-122.2, 47.7], [-122.2, 47.5], [-122.5, 47.5]], 'mumbai': [[72.8, 18.9], [72.8, 19.3], [73.0, 19.3], [73.0, 18.9], [72.8, 18.9]], 'delhi': [[76.8, 28.4], [76.8, 28.9], [77.4, 28.9], [77.4, 28.4], [76.8, 28.4]], 'bangalore': [[77.4, 12.8], [77.4, 13.2], [77.8, 13.2], [77.8, 12.8], [77.4, 12.8]] }; const normalizedName = region.toLowerCase().replace(/[,\s]+/g, ' ').trim(); if (places[normalizedName]) { return ee.Geometry.Polygon([places[normalizedName]]); } // Try to parse as coordinates if (region.includes(',')) { const parts = region.split(',').map(p => parseFloat(p.trim())); if (parts.length === 2 && !isNaN(parts[0]) && !isNaN(parts[1])) { return ee.Geometry.Point([parts[1], parts[0]]).buffer(10000); } } // Default to LA return ee.Geometry.Polygon([places['los angeles']]); } // Calculate spectral index async function calculateIndex(indexType, geometry, startDate, endDate) { // Implementation for various indices const collection = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') .filterDate(startDate, endDate) .filterBounds(geometry); const composite = collection.median().clip(geometry); let index; switch (indexType) { case 'NDVI': index = composite.normalizedDifference(['B8', 'B4']); break; case 'NDWI': index = composite.normalizedDifference(['B3', 'B8']); break; case 'EVI': index = composite.expression( '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', { 'NIR': composite.select('B8'), 'RED': composite.select('B4'), 'BLUE': composite.select('B2') } ); break; default: index = composite.normalizedDifference(['B8', 'B4']); } const stats = index.reduceRegion({ reducer: ee.Reducer.mean(), geometry: geometry, scale: 30, maxPixels: 1e9 }); return await new Promise((resolve, reject) => { stats.evaluate((result, error) => { if (error) reject(error); else resolve({ mean: result.nd || result.mean || 0 }); }); }); } // Yield prediction model async function buildYieldModel(cropType, groundTruth) { // Simplified yield model const model = { cropType: cropType, coefficients: { ndvi: 45.2, evi: 38.7, temperature: -0.8, precipitation: 0.12, intercept: 2.5 } }; // Calibrate with ground truth if available if (groundTruth) { // Adjust coefficients based on ground truth model.calibrated = true; } return model; } // Apply yield model async function applyYieldModel(model, geometry, startDate, endDate) { const ndvi = await calculateIndex('NDVI', geometry, startDate, endDate); const evi = await calculateIndex('EVI', geometry, startDate, endDate); // Simplified yield calculation const yield = model.coefficients.ndvi * ndvi.mean + model.coefficients.evi * evi.mean + model.coefficients.intercept; return Math.max(0, yield); } // Other helper functions function getHealthStatus(ndvi) { if (ndvi < 0.2) return 'Poor'; if (ndvi < 0.4) return 'Fair'; if (ndvi < 0.6) return 'Good'; return 'Excellent'; } function getHealthRecommendation(ndvi) { if (ndvi < 0.2) return 'Immediate intervention needed - check for disease or nutrient deficiency'; if (ndvi < 0.4) return 'Monitor closely - consider fertilization or irrigation'; if (ndvi < 0.6) return 'Healthy crop - maintain current practices'; return 'Optimal health - ready for harvest planning'; } function getMoistureLevel(ndwi) { if (ndwi < -0.3) return 'Very Dry'; if (ndwi < 0) return 'Dry'; if (ndwi < 0.3) return 'Adequate'; return 'Wet'; } function validatePrediction(predicted, groundTruth) { const mape = Math.abs((predicted - groundTruth) / groundTruth) * 100; return { accuracy: Math.max(0, 100 - mape), mape: mape, rmse: Math.sqrt(Math.pow(predicted - groundTruth, 2)) }; } function generateAgricultureRecommendations(results) { const recommendations = []; if (results.health && results.health.status === 'Poor') { recommendations.push('Apply fertilizer to improve crop health'); } if (results.moisture && results.moisture.irrigationNeeded) { recommendations.push('Irrigation required - soil moisture is low'); } if (results.pest && results.pest.riskLevel === 'High') { recommendations.push('Implement pest control measures immediately'); } if (results.stress && results.stress.overallRisk === 'High') { recommendations.push('Address stress factors to prevent yield loss'); } return recommendations; } // Send response function sendResponse(id, result) { const response = { jsonrpc: '2.0', id: id, result: result }; console.log(JSON.stringify(response)); } // Send error function sendError(id, code, message) { const error = { jsonrpc: '2.0', id: id, error: { code: code, message: message } }; console.log(JSON.stringify(error)); } // Stub functions for complex operations async function assessPestRisk(geometry, cropType, startDate, endDate, groundTruth) { return { level: 'Medium', area: '15%', type: 'Aphids', recommendations: ['Apply organic pesticide', 'Introduce beneficial insects'] }; } async function analyzeStress(geometry, startDate, endDate) { return { water: 0.3, nutrient: 0.2, disease: 0.1, overall: 'Low' }; } async function generateAgricultureMap(geometry, startDate, endDate, results) { return 'https://earthengine.googleapis.com/v1/projects/earthengine-legacy/thumbnails/agriculture-analysis:getPixels'; } async function estimateBiomass(geometry, startDate, endDate, equation) { return { above: 250, below: 50, total: 300 }; } async function calculateSequestrationRate(geometry, startDate, endDate) { return 5.2; // tons CO2/hectare/year } async function assessSpeciesDiversity(geometry, groundTruth) { return { shannon: 2.3, simpson: 0.85, richness: 45, dominant: ['Oak', 'Pine', 'Maple'] }; } async function assessForestHealth(geometry, startDate, endDate) { return { ndvi: 0.75, evi: 0.68, lai: 4.2, status: 'Healthy', stressors: [] }; } async function detectDeforestation(geometry, startDate, endDate) { return { area: 12.5, rate: 2.1, hotspots: [[0, 0]], drivers: ['Agriculture expansion', 'Urban development'] }; } function calculateCarbonCredits(carbonStock) { if (!carbonStock) return 0; return { credits: Math.floor(carbonStock.co2Equivalent / 10), value: Math.floor(carbonStock.co2Equivalent * 15), // $15 per ton CO2 currency: 'USD' }; } function generateForestRecommendations(results) { const recommendations = []; if (results.deforestation && results.deforestation.rate > 2) { recommendations.push('Implement forest protection measures'); } if (results.health && results.health.status !== 'Healthy') { recommendations.push('Monitor forest health indicators'); } if (results.diversity && results.diversity.shannonIndex < 2) { recommendations.push('Enhance species diversity through selective planting'); } return recommendations; } // Initialize on startup initializeEarthEngine().catch(error => { console.error('[MCP] Startup error:', error); });

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/Dhenenjay/axion-planetary-mcp'

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