reliefroute
Provides access to Google's Gemini API for multimodal understanding of field reports (text, images, audio), planning strategies, and reflective learning, enabling the agent to extract needs, assign supplies, and improve over time.
Uses the Google Maps Routes API to compute travel times and distances for dispatch planning and routing, supporting route simulation, detour calculation, and delivery optimization.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@reliefrouteparse this Tamil voice note: need food and water in Velachery urgently"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ReliefRoute
ReliefRoute is a flood-relief logistics agent for Chennai. It takes a field report (typed text, a photo, or a voice note, in English, Tamil, Tanglish or Hindi) and handles the rest:
it works out who needs what and how urgently
it assigns supplies from depots and loads them onto trucks with capacity limits and multi-stop routes
it detects when a route fails mid-delivery and replans
it scores the outcome and learns from it before the next run, including a dispatch policy trained with reinforcement learning (PyTorch) in an OpenEnv environment
Built for the Agent Wars challenge at GDG DevFest 2026.
Live app | |
MCP endpoint | |
Health check | |
Source | |
Architecture details |

The problem
During the Chennai floods, help requests arrive as WhatsApp voice notes, photos of handwritten lists and messages in mixed Tamil and English. Coordinators have to work out by hand:
what each message is asking for
which depot has the stock
which roads are still open
Roads close while trucks are already moving, and the lessons from one flood are rarely written down before the next one.
ReliefRoute automates that chain from the moment a report arrives to a scored, completed delivery plan.
Related MCP server: MCPs
What the agent does
Every dispatch runs the same seven stages. The web app lights them up as they complete.
flowchart LR
A["Field report<br/>text, photo, voice"] --> B["1 Understand<br/>Gemini multimodal"]
B --> C["2 Plan<br/>strategy + lessons"]
C --> D["3 Dispatch<br/>simulator step"]
D --> E{"4 Disruption?<br/>route blocked"}
E -->|yes| F["5 Self-heal<br/>replan or detour"]
F --> D
E -->|no| G["6 Score"]
G --> H["7 Learn<br/>lessons + policy"]
H -.->|next episode| CStage | What happens |
1 Understand | Gemini reads the report and any attached photo or audio. It returns structured needs (area, item, quantity, urgency 1–5) and road hazards. The agent validates the output: it clamps quantities and checks that coordinates fall inside Chennai. |
2 Plan | The agent picks a planning strategy: Gemini, a neural policy trained with reinforcement learning, or one of three rule-based strategies. It assigns each request to a depot, in stop order. A guardrail checks every plan Gemini produces before anything moves. |
3 Dispatch | The simulator loads the assignments onto trucks (2 per depot, 250 units each) and drives each truck's stops in order. It moves stock and computes leg distances, arrival times and reward. |
4 Disruption | On the first round, a bridge collapses on the longest leg that is not already detouring. That delivery fails. |
5 Self-heal | The agent sees which deliveries failed or did not fit on a truck, and replans them: a detour, a different depot or the next round. It gets up to three rounds. |
6 Score | The reward is converted to a percentage of the best possible outcome. |
7 Learn | The strategy's average score is updated, and the agent writes lessons that are fed into the next plan. |
Try it in three minutes
Under Training, click Run 5 episodes. Click it a second time.
The agent plays ten random flood scenarios.
Watch the Performance panel: score per episode, the change against the first five runs, and which strategy the bandit now prefers (
rl_policyis the trained neural policy).
Under Field report, click the Tanglish sample (or attach a photo, or record a voice note), then click Dispatch.
Read the result:
Map: orange dots are your report and blue dots are other open requests. Green lines are truck legs (depot to first stop, then stop to stop; hover for truck, stop number and arrival time). A red cross is the leg that broke; a dashed green line is the detour that replaced it.
Event log: each line is tagged with the stage that produced it.
Log tag | Meaning |
| What Gemini extracted from the report |
| The plan for that round, its reasoning, and each delivery |
| A disruption happened (the bridge collapse) |
| A blocked delivery is being replanned |
| The plan was corrected before dispatch (unknown depot, missing request, unsafe route) |
| A Gemini model ran out of quota, so the agent switched model |
| An external service failed, so the agent used a local method (rules, distance estimate) |
| Outcome as a percentage of the best possible |
| A lesson written to memory for the next run |
Architecture
flowchart LR
subgraph Client["Browser"]
UI["static/index.html<br/>report form, map, event log, charts"]
end
EXT["Other agents<br/>Gemini CLI, Google ADK"]
subgraph Server["FastAPI app on Vercel"]
API["main.py<br/>REST API"]
MCP["mcp_server.py<br/>MCP endpoint"]
AG["agent.py<br/>intake, planning, guardrails,<br/>failover, reflection, bandit"]
SIM["env.py<br/>flood simulator<br/>reset / step / state"]
MEM[("Memory<br/>lessons, policy stats, scores")]
end
subgraph Google["Google APIs"]
GEM["Gemini API"]
ROUTES["Maps Routes API"]
end
UI -->|HTTPS| API
EXT -->|JSON-RPC| MCP
API --> AG
MCP --> AG
AG <--> SIM
AG <--> MEM
AG --> GEM
AG --> ROUTESAgent (
agent.py) holds all the decision logic. Both the web API and the MCP server call the same functions.Simulator (
env.py) follows the OpenEnv contract (reset,step,state). It runs in-process, so an episode with the rule-based strategies takes milliseconds.relief_openenv/packages the same simulator as an OpenEnv environment server.Learned policy (
policy.py) runs the network trained byrl/train_policy.pyin plain Python frompolicy_weights.json, so the deployed app needs no PyTorch.Memory is a JSON document: lessons, per-strategy statistics and episode history. The browser keeps a copy and sends it back with each request. If a serverless instance restarts and loses its copy, learning is restored from the browser.
External calls go only to Google APIs: Gemini for understanding, planning and reflection, and the Maps Routes API for travel times.
The request lifecycle, simulator rules, scoring formula, learning loop and every failure path are documented with diagrams in docs/architecture.md.
How it meets the brief
Requirement | How ReliefRoute does it | Where |
End to end | One request goes from raw report to understood needs, plan, dispatch, recovery, score and lesson, with no human step |
|
Multimodal | Text, images and audio go to Gemini in a single call. The browser converts microphone recordings to WAV. |
|
Feedback loop | Every episode's score updates the policy and the lesson memory, and both shape the next episode |
|
Self-learning | 1. A neural dispatch policy trained with REINFORCE (PyTorch) in the simulator: weights updated over 6,000 episodes. 2. An epsilon-greedy bandit learns online which strategy scores best. 3. Gemini writes lessons that are injected into later planning prompts. |
|
Self-healing | Replanning after blocked routes; guardrail repair of bad plans; retries; a quota circuit breaker with model failover; a rule-based fallback for every Gemini step; distance estimates when Maps fails; memory restore after cold starts |
|
Google APIs only | Gemini API and Google Maps Routes API, called with Google API keys |
|
Deployable | Live on Vercel. A Dockerfile is included for Cloud Run. |
|
MCP | The agent's tools are exposed over MCP (Streamable HTTP) |
|
Reinforcement learning
rl/train_policy.py trains a dispatch policy with REINFORCE (PyTorch) by playing simulated floods. In every round it makes two decisions with two small networks (one hidden layer of 16 units each):
which request to load next, which also sets the truck stop order
which depot serves it
The inputs are hand-built features: urgency, quantity, effective distance, whether the route is flooded, stock coverage and how scarce the item is. Training used 6,000 episodes (about 4 minutes on a laptop CPU). Evaluation uses 500 scenarios the policy never saw during training, all with the mid-delivery bridge collapse switched on:
Strategy | Average score on 500 held-out scenarios |
Trained policy ( | 80.2% |
Same networks before training | 55.7% |
| 80.0% |
| 79.2% |
| 32.9% |
From scratch, the policy learns to match the best hand-written rule: it goes from 55.7% to 80.2%. It does not yet clearly beat that rule. The exported weights reproduce the PyTorch result exactly (80.2%) in pure Python, and that is what the live app runs as the rl_policy strategy.

To retrain:
pip install -r requirements-train.txt
python rl/train_policy.py --episodes 6000This writes policy_weights.json, rl/results.json and docs/rl_training.png.
OpenEnv environment
relief_openenv/ packages the simulator as a standard OpenEnv environment:
typed
ReliefAction,ReliefObservationandReliefStatemodelsa server built with OpenEnv's
create_appa typed
ReliefEnvClientan
openenv.yamlmanifest that passesopenenv validate --level static
Any OpenEnv-compatible trainer can therefore use it, for example TRL's GRPO.
pip install "openenv>=0.9"
uvicorn relief_openenv.server.app:app --port 8001from relief_openenv import Assignment, ReliefAction, ReliefEnvClient
with ReliefEnvClient(base_url="http://localhost:8001").sync() as env:
result = env.reset(seed=7)
while not result.done:
plan = [Assignment(need_id=n["id"], depot_id="D1") for n in result.observation.pending_needs]
result = env.step(ReliefAction(assignments=plan))
print(result.observation.score)Episodes run over OpenEnv's WebSocket session, one simulator per session. To build a container (from the repository root): docker build -f relief_openenv/server/Dockerfile -t reliefroute-openenv .
Run it locally
Requirements: Python 3.10 or newer. A Gemini API key from https://aistudio.google.com/apikey is optional; without one, the agent runs entirely on its rule-based fallbacks.
git clone https://github.com/Pranav-0710/reliefroute.git
cd reliefroute
python -m venv .venvActivate the environment. On Windows (PowerShell):
.venv\Scripts\Activate.ps1
$env:GEMINI_API_KEY = "your-key"On macOS or Linux:
source .venv/bin/activate
export GEMINI_API_KEY="your-key"Install the dependencies and start the server:
pip install -r requirements.txt
uvicorn main:app --port 8080Open http://localhost:8080.
Variable | Required | Default | Purpose |
| no | – | Enables Gemini. |
| no | the Gemini key | Key for the Maps Routes API |
| no |
| Order in which models are tried |
| no |
| Where memory is stored |
| no | – | Set to |
| no |
| Gemini calls one server instance may make per UTC day. Past it, the agent uses its rule-based fallbacks. |
Tests
pytest -qThe 19 tests run without network access or an API key. The OpenEnv test is skipped if the openenv package isn't installed. They cover:
the simulator contract and truck rules: capacity, stop order, arrival times, a full fleet
recovery after a blocked route
guardrail repair
the trained policy running without PyTorch
the bandit learning to avoid the weakest strategy
scores staying within 0–100% across 120 episodes
memory restore after a cold start
the quota circuit breaker and the daily Gemini budget
per-client rate limits
keyword intake
the MCP handshake and tool calls
the OpenEnv environment and server
the full web flow
Use it from another agent (MCP)
The MCP endpoint is stateless Streamable HTTP with JSON responses.
Tool | Input | Returns |
|
| Structured needs and hazards |
|
| Deliveries, self-heal events, score and new lessons |
| optional | Strategy and score for each episode |
| – | Lessons, policy statistics and recent scores |
List the tools:
curl -s https://reliefroute.vercel.app/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Call a tool:
curl -s https://reliefroute.vercel.app/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"dispatch_relief","arguments":{"text":"Adyar: 200 people need drinking water, urgent"}}}'Gemini CLI (~/.gemini/settings.json):
{ "mcpServers": { "reliefroute": { "httpUrl": "https://reliefroute.vercel.app/mcp" } } }Google ADK:
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
reliefroute = McpToolset(connection_params=StreamableHTTPConnectionParams(url="https://reliefroute.vercel.app/mcp"))HTTP API
Method | Path | Purpose |
|
| Web app |
|
| Status, whether Gemini and the trained policy are available, model order, today's Gemini budget use |
|
| Multipart form: |
|
| JSON |
|
| A sample scenario for the initial map |
|
| Current memory |
|
| Clear memory |
|
| MCP JSON-RPC endpoint |
The public deployment limits each client address to 8 dispatches, 60 training requests, 10 costly MCP tool calls and 5 memory resets per 10 minutes. Over the limit, the server returns HTTP 429 with a Retry-After header.
Repository layout
Path | Contents |
| Flood simulator: depots, trucks, requests, floods, the bridge collapse, reward |
| Intake, planning strategies, guardrail, Gemini failover and budget, Maps ETAs, reflection, bandit, memory |
| Learned policy: features, decision procedure, pure-Python inference |
| Trained policy weights |
| PyTorch REINFORCE training and its evaluation results |
| The simulator as an OpenEnv environment: models, server, client, manifest, Dockerfile |
| FastAPI server: web app, REST API, MCP route, rate limits |
| MCP protocol handling and tool definitions |
| The operations console (single file, no build step) |
| Automated tests |
| Container image for Cloud Run or any container host |
| Diagrams and technical reference |
Deployment
The live app runs on Vercel, which detects the FastAPI app in main.py automatically:
npx vercel deploy --prodSet GEMINI_API_KEY under the project's Environment Variables first. The live deployment sets GEMINI_MODELS=gemini-3.5-flash-lite,gemini-flash-latest,gemini-3.8-flash, which starts with the model that has the most free-tier quota.
To run on Google Cloud Run instead, use the included Dockerfile. This needs a project with billing enabled:
gcloud run deploy reliefroute --source . --region asia-south1 --allow-unauthenticated --set-env-vars GEMINI_API_KEY=your-keyKnown limitations
Google Maps travel times are not live yet. The Routes API call is implemented, but the deployed key is not authorised for that API (it returns
401). Enabling the Routes API requires a Google Cloud project with billing, and ours is closed. The agent falls back to distance estimates, and the log labels those ETAs "estimate". SettingMAPS_API_KEYto a key with the Routes API enabled switches to real travel times with no code change.Gemini quota is limited. The deployment uses the Gemini free tier, which allows few requests per day. When a model is exhausted, the circuit breaker moves to the next one. If every model is exhausted, the agent continues on rule-based intake and planning, which only understands English keywords and known area names.
The scenario data is simulated. Depot stock, the other requests, flood zones and the bridge collapse are all simulated. Locations are real Chennai localities with approximate coordinates. Distances are straight-line multiplied by a 1.3 road factor, not a road network.
Memory is not durable. It is a JSON file on the serverless instance, plus a copy in each browser. It is not reliably shared between instances or users. A production version would store it in Firestore.
The RL policy is trained offline and is small. Its weights are updated in training, not while the app runs; online learning is the bandit and the Gemini lessons. It matches the best hand-written rule rather than clearly beating it. Gemini itself is not fine-tuned.
There is no authentication. Anyone with the link can run dispatches and reset memory. Per-address rate limits and a daily Gemini budget cap the damage, but both are kept per server instance. The MCP server is minimal: tools only, no sessions or streaming.
Next steps
Train a small open language model as the planner with GRPO (Hugging Face TRL) against the
relief_openenvserver.Give the RL policy truck-aware features (load, current position) so it can learn routing that beats the rules.
Store memory in Firestore so learning is shared and durable.
Use the Routes API route matrix for real road distances, and the Route Optimization API for the truck routes.
Connect real depot inventory and a phone or SMS intake line.
Add authentication and per-organisation memory.
Author
Built by jey pranav (@Pranav-0710).
License
MIT. See LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Remote MCP server exposing SMI Aware tools, resources, and skills over Streamable HTTP.
Streamable HTTP MCP server exposing planner flows, tasks, and squads.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Read-only MCP server for the OPERANT AI operating-agent calibration benchmark.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceProduction-ready MCP server exposing India-specific public data, weather/environment, transport, and maps/address APIs through unified tools for AI agents.-
- AlicenseNot gradedqualityCmaintenanceExposes remote, agent-facing MCP endpoints over Streamable HTTP for web search, webpage parsing, local knowledge-base retrieval and document creation, and delegation of tasks to configurable LLM providers. Also bundles an admin console with onboarding, provider/model configuration, API-key management, and call logging.MIT
- AlicenseNot gradedqualityCmaintenanceServes as a practical starting point for AI agents, providing a stateless HTTP-based MCP endpoint with validated example tools for time queries, text formatting, and arithmetic calculations.204 npm1MIT
- AlicenseNot gradedqualityAmaintenanceExposes a running DeepSeek Harness as an MCP endpoint so any other agent or script can create workspaces and sessions, hand coding tasks to the DSH agent, read and write files, run shell commands, and invoke permitted harness tools under the same sandbox, transcript, and permission policy as the DSH UI.1MIT