Inspiration
Gardens are personal. People invest real time and emotion into their plants — yet most gardening apps are static reference tools that forget everything the moment you close them. We wanted to build something different: an agent that knows your garden, remembers your preferences across sessions, and takes action on your behalf.
GardenState started from one question: what if your garden had an AI that grew smarter the more you used it?
What We Built
GardenState is a personal garden management agent powered by Gemini 2.5 Flash, MongoDB Atlas, and Google ADK. Users chat naturally with their garden through a mobile-responsive web app.
Memory that persists
Most chatbots forget everything on refresh. GardenState has two persistence layers:
- Long-term memory — the agent stores facts, named preferences (
experience_level,watering_time,advice_style), and personal plant notes in MongoDB. A user who says "I only use organic fertilizer" never has to say it again. - Chat history — full per-card transcripts with deterministic session IDs survive logout and browser close.
It doesn't just advise — it acts
| Capability | How it works |
|---|---|
| Vision | Upload any photo (HEIC/JPEG/PNG) → Gemini identifies species and diagnoses health |
| Smart photo matching | Auto-matches identified plant to an existing care card, or offers to create a new one |
| Weather | Open-Meteo live forecast with garden alerts: frost risk, heat stress, skip-watering signals |
| RAG knowledge base | 18 plant-care docs embedded with gemini-embedding-001 (3072 dims) in Atlas Vector Search |
| Smart home control | Start/stop irrigation zones and trigger camera snapshots via natural conversation |
| Behavioral adaptation | Tone and detail adapt to the user's experience level (beginner/intermediate/expert) and current season |
| Plant status dots | Color-coded health indicator on every card — updated automatically after each care check |
How We Built It
Browser (SPA)
└── FastAPI (streaming NDJSON)
└── Google ADK Runner
├── Gemini 2.5 Flash (reasoning + vision)
├── 10+ Python tools (weather, sensors, memory, RAG, smart home)
└── MongoDB MCP → Atlas
├── plants / sensor_readings / tasks
├── care_knowledge (Vector Search, 3072-dim embeddings)
└── user_memories (facts · preferences · plant notes)
- Agent layer: Google ADK orchestrates all tool calls. The system instruction is structured into clear sections — identity, tool rules, response style, memory rules, and standard workflows — keeping Gemini's decisions consistent.
- Database: MongoDB Atlas stores everything. Memory is split into three structured fields rather than a flat list, so the agent injects only what's relevant each turn.
- Backend: FastAPI with streaming NDJSON for token-by-token chat rendering.
- Frontend: Single-page vanilla JS, fully mobile-responsive — off-canvas sidebar and bottom-sheet modals on phones.
- Deployment: Google Cloud Run with a custom Dockerfile installing both Python and Node.js (required for the MongoDB MCP server's
npxsubprocess).
Challenges
SSL failure between Cloud Run and MongoDB Atlas was our hardest debugging session. The container crashed at startup with TLSV1_ALERT_INTERNAL_ERROR. The surface error pointed to DNS, but the real cause was Atlas network access configuration. We only found it by reading raw Cloud Run logs directly.
Memory architecture required deliberate design. A flat free-text facts list quickly becomes noisy and wastes tokens. We split memory into three structured fields — facts, preferences, and plant notes — so Gemini receives clean, relevant context without attention dilution.
Node.js inside Cloud Run was a documented gotcha: ADK's default deploy builds a Python-only image, so the MongoDB MCP server's npx call fails silently in production. We wrote a custom Dockerfile that installs Node 20 alongside Python to solve it.
What We Learned
Building a real agent means thinking hard about when to act vs. when to ask. Tool descriptions and system instructions matter as much as the model — vague instructions produce inconsistent behavior regardless of model quality.
MongoDB Atlas Vector Search made RAG far more accessible than expected. And Gemini's native multimodal capability turned plant photo diagnosis from a complex multi-step pipeline into a single tool call.
Most importantly: the difference between a chatbot and an agent is memory plus action. GardenState has both.
Built With
- atlas
- docker
- fastapi
- gemini-2.5-flash
- google-adk
- google-ai-studio
- google-cloud-build
- google-cloud-run
- google-maps-geocoding-api
- javascript
- mongodb-atlas
- mongodb-mcp-server
- open-meteo-api
- perenual-plant-api
- python
- vector
Log in or sign up for Devpost to join the conversation.