Skip to content
Advance Labs

Athena AI challenge submission

Earthquake Activity Explorer

Built in under an hour for the Athena AI interview challenge. It's an MCP server sitting on top of the live USGS earthquake catalogue, rendered as an interactive widget inside an Athena agent.

Open the live widgetSource on GitHub

MCP endpoint: https://athena-quake-mcp.vercel.app/mcp

What it does

Ask the agent about recent seismic activity, either worldwide or near a place, and it pulls the live catalogue through MCP and draws it. The map plots every epicentre, sized by magnitude and coloured by depth. Nobody drew the plate boundaries on there. They show up because that's where the earthquakes are.

The widget

The brief asked for at least two meaningful interactions. There are four, and each one answers a question you'd actually ask about earthquakes.

Time range
24 hours, 7 days, or 30 days. Filters the map and the event list together.
Magnitude threshold
All, 4+, 5+, or 6+. Drops about 100 events down to the three that actually matter.
Sort order
Recent, strongest, or deepest. Sorting by depth surfaces the deep focus subduction quakes that a magnitude sort buries.
Event selection
Click a list row or a circle on the map. It expands the full USGS record (UTC time, depth, coordinates, felt reports, significance) and dims every other epicentre.

One USGS query backs all of it. Every filter, sort, and selection runs in the browser, so nothing costs a round trip and the widget never needs network access of its own. That last part matters more than it sounds, because iframe security policy varies a lot between chat hosts.

The part that was actually hard

Chat hosts don't agree on how a tool returns UI. Some render the resource embedded in the tool result. Others read a pointer off the tool definition, fetch the widget once as an empty template, then push the data in afterwards at runtime. Those two models are incompatible if you build for one and assume the other.

So the widget builds two ways from one renderer. One version has the data baked in. The other ships an empty shell that hydrates itself when the host hands it the result. Same code draws both, so the UI can't drift between them. Hosts that support no widget at all still get a full text summary and structured content, so the model can answer either way.

Stack

Data
USGS Earthquake Catalog (FDSN) for events. Open-Meteo geocoding to turn “near Tokyo” into the lat/lon and radius the USGS query needs. Both public, no API keys.
Transport
Hand rolled JSON-RPC 2.0 over Streamable HTTP. Zero runtime dependencies.
Tools
explore_earthquakes renders the widget. list_significant_earthquakes finds where the notable activity is.
Hosting
Node serverless function on Vercel. Public endpoint, no auth.

Who built it

Lucas Krawczak

Founder & Engineer, Advance Labs Inc.

I founded Advance Labs; my brother Matthew heads its game development. We're an independent Canadian applied AI studio, federally incorporated, and we build and ship our own products. Most of my work right now is on the measurement side of AI search: figuring out what AI engines actually say about a business and why a competitor gets named instead. That means I spend a lot of my time doing exactly this kind of thing, wiring live public data into agent tooling and making the result something a person can poke at.

Our tagline is “we build until it works,” which is roughly how this one went. The first version of the widget rendered the wrong location in one host, and finding out why meant reading the server logs to see which resource the host asked for. It was asking for a different one than I assumed.

Questions about any of it, or want me to walk through the code, just reply and I'll get on a call.