Skip to main content
Glama

Axion Planetary MCP

by Dhenenjay
index.jsβ€’10.4 kB
#!/usr/bin/env node /** * Earth Engine MCP Server * Main entry point for Model Context Protocol integration */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ToolSchema } from '@modelcontextprotocol/sdk/types.js'; import ee from '@google/earthengine'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; // Import our calibrated models const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Dynamic import for CommonJS modules let models; try { const modelsPath = path.join(__dirname, 'models', 'calibrated-geospatial-models.cjs'); // Convert Windows path to file URL for ESM import const modelUrl = process.platform === 'win32' ? 'file:///' + modelsPath.replace(/\\/g, '/') : modelsPath; models = await import(modelUrl); } catch (error) { process.stderr.write(`Failed to load models: ${error}\n`); process.exit(1); } // Initialize Earth Engine let eeInitialized = false; async function initializeEarthEngine() { if (eeInitialized) return true; try { // Check for service account credentials from GOOGLE_APPLICATION_CREDENTIALS const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS; if (credentialsPath && fs.existsSync(credentialsPath)) { const key = JSON.parse(fs.readFileSync(credentialsPath, 'utf8')); return new Promise((resolve) => { ee.data.authenticateViaPrivateKey(key, () => { ee.initialize(null, null, () => { eeInitialized = true; resolve(true); }, (error) => { // Log to stderr, not stdout process.stderr.write(`Failed to initialize Earth Engine: ${error}\n`); resolve(false); }); }, (error) => { process.stderr.write(`Failed to authenticate Earth Engine: ${error}\n`); resolve(false); }); }); } else { // Skip OAuth authentication in MCP server context process.stderr.write('No GOOGLE_APPLICATION_CREDENTIALS found\n'); return false; } } catch (error) { process.stderr.write(`Earth Engine initialization error: ${error}\n`); return false; } } // Define available tools const TOOLS = { earth_engine_init: { schema: { type: "function", function: { name: "earth_engine_init", description: "Initialize Earth Engine connection", parameters: { type: "object", properties: {}, required: [] } } }, handler: async () => { const success = await initializeEarthEngine(); return { success, message: success ? 'Earth Engine initialized' : 'Failed to initialize' }; } }, wildfire_risk_assessment: { schema: { type: "function", function: { name: "wildfire_risk_assessment", description: "Assess wildfire risk for a specified region", parameters: { type: "object", properties: { region: { type: "string", description: "Region name or coordinates" }, startDate: { type: "string", description: "Start date (YYYY-MM-DD)" }, endDate: { type: "string", description: "End date (YYYY-MM-DD)" }, indices: { type: "array", items: { type: "string" }, description: "Vegetation indices to calculate" } }, required: ["region"] } } }, handler: async (params) => { try { const result = await models.wildfireRiskAssessment(params); return result; } catch (error) { return { success: false, error: error.message }; } } }, flood_risk_assessment: { schema: { type: "function", function: { name: "flood_risk_assessment", description: "Assess flood risk for a specified region", parameters: { type: "object", properties: { region: { type: "string", description: "Region name or coordinates" }, startDate: { type: "string", description: "Start date (YYYY-MM-DD)" }, endDate: { type: "string", description: "End date (YYYY-MM-DD)" }, floodType: { type: "string", enum: ["urban", "coastal", "riverine", "snowmelt"], description: "Type of flood to assess" } }, required: ["region"] } } }, handler: async (params) => { try { const result = await models.floodRiskAssessment(params); return result; } catch (error) { return { success: false, error: error.message }; } } }, agricultural_monitoring: { schema: { type: "function", function: { name: "agricultural_monitoring", description: "Monitor agricultural conditions and crop health", parameters: { type: "object", properties: { region: { type: "string", description: "Region name or coordinates" }, cropType: { type: "string", description: "Type of crop (corn, wheat, soybeans, etc.)" }, startDate: { type: "string", description: "Start date (YYYY-MM-DD)" }, endDate: { type: "string", description: "End date (YYYY-MM-DD)" } }, required: ["region"] } } }, handler: async (params) => { try { const result = await models.agriculturalMonitoring(params); return result; } catch (error) { return { success: false, error: error.message }; } } }, deforestation_detection: { schema: { type: "function", function: { name: "deforestation_detection", description: "Detect deforestation and forest loss", parameters: { type: "object", properties: { region: { type: "string", description: "Region name or coordinates" }, baselineStart: { type: "string", description: "Baseline period start date" }, baselineEnd: { type: "string", description: "Baseline period end date" }, currentStart: { type: "string", description: "Current period start date" }, currentEnd: { type: "string", description: "Current period end date" } }, required: ["region"] } } }, handler: async (params) => { try { // Set default dates if not provided if (!params.baselineStart) params.baselineStart = '2023-01-01'; if (!params.baselineEnd) params.baselineEnd = '2023-03-31'; if (!params.currentStart) params.currentStart = '2023-10-01'; if (!params.currentEnd) params.currentEnd = '2023-12-31'; const result = await models.deforestationDetection(params); return result; } catch (error) { return { success: false, error: error.message }; } } }, water_quality_monitoring: { schema: { type: "function", function: { name: "water_quality_monitoring", description: "Monitor water quality in lakes, rivers, and other water bodies", parameters: { type: "object", properties: { region: { type: "string", description: "Water body name or coordinates" }, startDate: { type: "string", description: "Start date (YYYY-MM-DD)" }, endDate: { type: "string", description: "End date (YYYY-MM-DD)" }, waterBody: { type: "string", enum: ["lake", "river", "reservoir", "coastal"], description: "Type of water body" } }, required: ["region"] } } }, handler: async (params) => { try { const result = await models.waterQualityMonitoring(params); return result; } catch (error) { return { success: false, error: error.message }; } } } }; // Create MCP server const server = new Server( { name: 'earth-engine-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); // Handle tool listing server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: Object.values(TOOLS).map(tool => tool.schema) }; }); // Handle tool execution server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const tool = TOOLS[name]; if (!tool) { throw new Error(`Unknown tool: ${name}`); } try { const result = await tool.handler(args || {}); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify({ error: error.message }, null, 2) } ], isError: true }; } }); // Start the server async function main() { process.stderr.write('Starting Earth Engine MCP Server...\n'); // Initialize Earth Engine on startup await initializeEarthEngine(); const transport = new StdioServerTransport(); await server.connect(transport); process.stderr.write('Earth Engine MCP Server running\n'); process.stderr.write(`Available tools: ${Object.keys(TOOLS).join(', ')}\n`); } main().catch((error) => { process.stderr.write(`Server error: ${error}\n`); process.exit(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/Dhenenjay/axion-planetary-mcp'

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