Inspiration
I've seen and read accounts of what 911 dispatchers and first responders actually deal with during a wildfire or flood — a radio call comes in ("the wind shifted, Engine 4 is trapped"), and someone has to translate that panic into an updated map in seconds, while also getting the right warning out to the people in its path. What struck me is that the hard part was never a lack of urgency on the human side. It was the software: even a good dispatcher is stuck clicking through GIS tools, drawing polygons, searching a database, updating a status, while the fire doesn't wait. The numbers back this up — NENA's 2025 Pulse of 9-1-1 report found nearly 70% of telecommunicators experience daily pre-shift stress and 88% of Emergency Communications Centers had a technology outage in the past year, on top of 74% still reporting unfilled positions. These are people making life-or-death calls in seconds, on systems that are often working against them.
As an AI engineer, that gap is exactly the kind of problem I wanted to build for, something that removes the friction between hearing it and acting on it, without taking the decision out of human hands. WebMCP made that possible in a very direct way: instead of an agent guessing its way through a UI, you tell it exactly what it's allowed to do, and a human approves it. That's Aegis — an agent-native dispatch map where the AI listens and drafts the response, and the dispatcher keeps final authority over every action that hits the map.
What it does
Aegis is an emergency dispatch dashboard that an AI agent can act on directly through WebMCP. A dispatcher pastes (or eventually speaks) a radio transcript to ChatGPT. The agent discovers five tools we've exposed on the page and drafts real map actions:
draft_hazard_zone— mark a fire/flood zone at exact coordinatesupdate_unit_status— flag a trapped unit as Code Redrelocate_unit— move an existing unit to new coordinatesdeploy_unit— spawn a new unit onto the mapdraft_evacuation_alert— prepare a broadcast to a sector
None of these mutate the live map directly. Every tool call fires into a pending-actions queue in the sidebar, and the human dispatcher has to click Approve before anything changes. A three-minute manual workflow becomes a few seconds of review and one click — without removing the human from the decision.
How we built it
Frontend is Next.js, React, and Tailwind CSS v4. The map is React-Leaflet with high-contrast tiles so units and hazards are legible at a glance.
For WebMCP, we use @mcp-b/webmcp-polyfill and register five tools against document.modelContext.registerTool, each with a strict JSON inputSchema (typed lat/lng floats, required fields) so the agent can't pass malformed data.
The execute function for each tool never touches state directly — it dispatches a CustomEvent that a listener in our root component catches and pushes into a pending-actions array. Only the approve/reject buttons, driven by human clicks, actually update the units and hazards in React state. We call this the Event Bridge, and it's the whole safety model: the agent can propose, only the human can commit.
Challenges we ran into
The biggest issue was a race condition specific to WebMCP in a single-page app: ChatGPT's agent would try to call our tools before React had finished hydrating, so document.modelContext wasn't ready yet and the handshake failed. We fixed this by registering the polyfill and tools outside the normal component lifecycle (in a useEffect with no dependency gating on other app state), so the tools are available as early as possible and the agent gets a reliable list on first contact.
We also had to think carefully about schema strictness — early versions let the agent pass loosely-typed coordinates, which occasionally produced markers in the ocean. Tightening the inputSchema to required numeric types fixed this.
Accomplishments that we're proud of
The part we're most proud of is that the safety architecture isn't a UI suggestion — it's structural. There's no code path where a WebMCP tool call reaches the map without passing through the approval queue. That was a deliberate constraint we kept even when it would have been faster to just let execute write to state directly.
We also built a "kinetic" map layer: when a relocation is approved, the unit marker animates across the map to its new position instead of snapping there, so it's visually obvious that an agent action produced a real, physical change on a live map — not just a database update.
What we learned
WebMCP is genuinely good at separating concerns that LLMs are bad at from ones they're good at. The agent is good at reading "Engine 4 is trapped" and inferring that means Code Red — semantic reasoning over messy text. It's not good at rendering, coordinate math, or knowing what's safe to commit to a live system. WebMCP let us keep the LLM entirely in the reasoning lane and keep our own deterministic code in charge of anything that touches the map or the data.
What's next for Aegis: Agent-Native Emergency Dispatch
The text-transcript step is still a manual bridge. The next version removes it: live WebRTC audio from real radio traffic, transcribed in real time, feeding continuously into the WebMCP agent so the map updates itself as a fire department's radio chatter comes in — with the same human-approval queue standing between the agent and the live map.
Built With
- leaflet.js
- nextjs
- openai
- react
- tailwind
- typescript
- vercel
- webmcp
Log in or sign up for Devpost to join the conversation.