Bumi Watch — Project Story
Inspiration
Indonesia is one of the world's most environmentally complex countries — home to over 10% of global tropical forests, sitting on the Pacific Ring of Fire, and facing some of Southeast Asia's worst urban air pollution. Yet for most Indonesians, the question "Bagaimana kondisi lingkungan di sekitar kita?" has no easy answer.
Environmental data exists — BMKG publishes earthquake feeds, NASA FIRMS tracks fire hotspots from space, WAQI monitors air quality sensors across cities. But this data is scattered, technical, and inaccessible to the average person. A journalist researching air pollution in Riau has to check three different government portals. A policymaker trying to understand the relationship between deforestation and flood risk has to manually cross-reference datasets.
We asked ourselves: What if you could just ask?
That question became Bumi Watch — a platform that turns Indonesia's fragmented environmental data into a single, conversational AI that anyone can talk to in Bahasa Indonesia or English.
What it does
Bumi Watch is an AI-powered environmental intelligence platform for Indonesia. It continuously collects real-time data from four live sources:
- 🔥 NASA FIRMS — active fire hotspots detected by MODIS and VIIRS satellites
- 💨 WAQI — air quality index (PM2.5, PM10, O3) across 25+ Indonesian cities
- 🌋 BMKG — earthquake events and weather alerts from Indonesia's meteorology agency
- 🌧️ Open-Meteo — rainfall data with drought and flood risk classifications
All data is indexed into Elastic Cloud (Jakarta region) every 30 minutes. Users interact through a natural language interface powered by Gemini 2.5 Flash, which queries Elastic through the official Elastic MCP server to retrieve real, cited data.
The platform's key feature is cross-source correlation — something no generic AI chatbot can replicate:
"Kenapa kualitas udara di Riau buruk minggu ini?"
→ AQI spiked to 187 (Unhealthy) · NASA FIRMS detected 1,247 new hotspots · BMKG shows no rainfall in 11 days · winds pushing smoke inland toward Pekanbaru
📍 Sources: WAQI · NASA FIRMS · BMKG · Open-Meteo
How we built it
Architecture
The system is built in three layers:
Layer 1 — Data Pipeline
A scheduled Node.js pipeline fetches from all four sources every 30 minutes and bulk-indexes into Elastic Cloud using 9 custom index schemas optimized for geo-queries and time-range aggregations.
NASA FIRMS → fetchFireHotspots.js → bumi-fire-hotspots
BMKG → fetchBMKG.js → bumi-bmkg-events
WAQI → fetchAirQuality.js → bumi-air-quality
Open-Meteo → fetchRainfall.js → bumi-rainfall
We built a coordinate-to-province mapping system covering all 34 Indonesian provinces using bounding box geospatial logic, so every fire hotspot (which NASA FIRMS only provides as lat/lon coordinates) gets correctly attributed to its province.
Layer 2 — AI Agent
A custom query router detects province names, time ranges, and environmental topics from natural language — in both Bahasa Indonesia and English — before constructing the appropriate Elastic queries. This means Gemini always has real data as context rather than relying on training data.
The Elastic MCP server (@elastic/mcp-server-elasticsearch) is deployed on Google Cloud Run and exposes Elastic as a set of tools that Google Cloud Agent Builder can call natively. This satisfies the competition's Partner MCP requirement while enabling authentic data retrieval.
$$\text{Answer Quality} = f(\text{Real Data}) \gg f(\text{Training Data})$$
Layer 3 — Frontend
A React + Vite dashboard with Leaflet maps, real-time data cards, and a chat interface. The frontend calls the Express agent API, which orchestrates Gemini queries against live Elastic data.
Key Technical Decisions
- Elastic Cloud over self-managed — Jakarta region (asia-southeast2) for minimum latency to Indonesian users
- Gemini 2.5 Flash over Pro — lower latency for conversational responses with sufficient reasoning capability
- MCP over direct Elastic API — native integration with Agent Builder, cleaner tool abstraction for Gemini
- Node.js pipeline over Python — unified JavaScript stack across pipeline, agent, and frontend
Challenges we ran into
1. Elastic MCP Protocol Compatibility
The biggest technical challenge. Google Cloud Agent Builder uses StreamableHTTPConnectionParams to connect to MCP servers, but Elastic's official MCP server is a stdio-based process. We had to bridge this using supergateway to wrap the stdio MCP server and expose it over SSE/HTTP for Agent Builder to consume. This took multiple iterations of debugging protocol mismatches between the MCP client and server.
2. Elastic Serverless vs Hosted
We initially deployed on Elastic Cloud Serverless (for simplicity), but discovered mid-development that the official Elastic MCP server was designed for Hosted deployments. The API endpoint formats differ (.elastic.cloud vs .elastic-cloud.com), which caused silent connection failures. We migrated to a Hosted deployment in Jakarta, which resolved the MCP compatibility issues.
3. Province Attribution from Coordinates
NASA FIRMS provides fire data as raw coordinates only — no province names. We built a custom bounding-box lookup system mapping lat/lon to all 34 Indonesian provinces. The challenge was handling overlapping bounding boxes near province borders, which we resolved with priority ordering.
4. Cross-Source Correlation Context Window
Passing context from four data sources simultaneously into a single Gemini prompt required careful prompt engineering to ensure Gemini synthesized the data rather than just listing it. We developed a structured context builder that formats each data source's output consistently, making it easy for Gemini to reason across sources.
5. API Reliability
Several data sources proved unreliable during development — Global Forest Watch's RW API returned 500 errors consistently, the GLAD deforestation API endpoint changed, and OpenAQ's v3 API had parameter compatibility issues. We systematically replaced unreliable sources with more stable alternatives and built graceful fallback logic throughout the pipeline.
Accomplishments that we're proud of
Real cross-source environmental reasoning — When asked why Riau's air quality is bad, Bumi Watch doesn't guess. It cross-references fire hotspot counts, wind direction from BMKG, and rainfall absence from Open-Meteo to construct a causal explanation backed by satellite data. This level of multi-source environmental intelligence is genuinely novel.
34-province coordinate mapping — We built a complete geospatial attribution system for all Indonesian provinces from scratch, enabling province-level analysis of NASA FIRMS satellite data that only provides raw coordinates.
Bilingual agent — The query router detects Bahasa Indonesia and English automatically, routing the same question correctly regardless of language. Province names in both languages are recognized (e.g., "Kalimantan Timur" and "East Kalimantan").
Production-grade data pipeline — The pipeline runs reliably with graceful error handling, automatic retry logic, and 503/timeout fallbacks. It's designed to keep running even when individual data sources are temporarily unavailable.
MCP-native Elastic integration — Successfully connecting Google Cloud Agent Builder to a live Elastic Cloud cluster through the official Elastic MCP server, deployed on Cloud Run — exactly as the competition intended.
What we learned
Environmental data is harder than it looks. Every API has quirks — BMKG stores earthquake timestamps with local timezone suffixes that break standard date parsing, NASA FIRMS returns CSV that sometimes contains error HTML instead of data, and GeoJSON sources for Indonesian province boundaries vary significantly in quality and format.
MCP is powerful but nascent. The Model Context Protocol is the right abstraction for connecting AI agents to external data sources, but tooling and documentation are still maturing. We spent significant time navigating protocol version mismatches and transport layer incompatibilities between different MCP implementations.
Context window design matters as much as the model. The quality of Gemini's environmental answers improved dramatically once we structured the data context properly — with clear source labels, consistent formatting, and explicit time ranges. The model is only as good as the context you give it.
Cross-language NLP is non-trivial at the query routing level. Building a router that correctly identifies "gempa besar" and "significant earthquake" as the same intent — and maps "Kalimantan" and "Borneo" to the same province set — required building explicit keyword mappings for Indonesian environmental vocabulary.
What's next for Bumi-Watch
Deforestation integration — We built the index schema and pipeline infrastructure for deforestation data, but the GLAD API proved unreliable during the hackathon period. We plan to integrate Global Forest Watch's tile-based API and Google Earth Engine for reliable deforestation alerts.
Province drill-down analytics — Adding time-series trend analysis per province, so users can ask "How has Jakarta's AQI changed over the past year?" with historical data.
Proactive alerts — A push notification system that alerts subscribed users when environmental thresholds are crossed in their province — e.g., AQI > 150, earthquake magnitude > 5.0, or sudden spike in fire hotspots.
Mobile app — A lightweight Android/iOS app targeting Indonesian policymakers, environmental journalists, and NGO field workers who need real-time environmental intelligence on the go.
Expanded data sources — Sea surface temperature (for coral bleaching risk), BNPB disaster events, and CO₂ emissions by province to build a complete environmental risk profile for every region in Indonesia.
Government partnerships — We believe Bumi Watch's architecture — a unified query layer over Indonesia's fragmented environmental data — has genuine utility for KLHK (Ministry of Environment), BNPB (National Disaster Management), and regional governments. We're exploring pathways to make this infrastructure available as a public service.
Bumi Watch — because 270 million Indonesians deserve to know what's happening to their Earth.
Bumi = Earth in Bahasa Indonesia
Log in or sign up for Devpost to join the conversation.