Inspiration
Across South Asia, Africa and Latin America, homes pump water from a ground sump into a rooftop tank, on power that comes and goes on a schedule. People guess when to run the pump. Guess wrong and the motor dry-runs and burns out, or the tank overflows onto the terrace. A voice assistant could manage this, but the moment an AI can switch on a real motor, "the model said so" is not good enough.
What it does
Jal is an Alexa+ add-on built as a self-hosted MCP server over Streamable HTTP. You can ask "do we have enough water for tomorrow morning?" or "should I run the pump?", and Jal answers from a deterministic forecast. It never starts anything on its own:
- The assistant proposes.
propose_pump_runreturns a plan and a signed one-time token. It does not start the pump. - The human confirms.
confirm_pump_runneeds that token: HMAC-signed, 60-second TTL, single use, and rejected if the tank or sump changed since the proposal. - The device enforces. The device twin checks its own invariants (tank full, sump empty, no power, run too long) on every command and every 1-second tick. It refuses unsafe starts with HTTP 409 even when the command skips the server, and auto-stops a running pump the moment the sump runs dry. Stops are always allowed.
A second device, a water heater, runs through the same guardrail with no heater-specific guardrail code: just a policy file and a twin device.
How we built it
- Twin (FastAPI): physics simulation and invariants.
- Guardrail (Python library): policy, tokens, rate limits, cooldowns and a SQLite audit log shared with the twin.
- MCP server (FastMCP): 9 tools, every output validated against JSON Schemas.
- Web dashboard (React, Vite): a real MCP client with browser speech, so judges can try the full flow without Alexa+.
- Delivery: Caddy puts it all behind one port, and Docker Compose runs it with one command.
- Tests: 90 tests, including an end-to-end test over the real Streamable HTTP transport.
No LLM computes any number or makes any safety decision.
Challenges
- The Alexa+ CLI was gated for our account, so the add-on never ran inside Alexa+. We built a simulated Alexa+ experience in the web app instead and documented it in our friction log.
- Getting the production build to route
/mcpand the device API through one origin took a reverse proxy. - Making sure a schema check could never block an emergency stop meant validating only after the stop had happened.
What we learned
Safe physical actuation over MCP is an architecture problem, not a prompt problem. The model should only talk. Code should compute. The device should trust nobody. MCP would benefit from a standard "requires human confirmation" tool annotation, which is our top feature request.
Log in or sign up for Devpost to join the conversation.